README
This document contains the R workflow for processing and analysing the raw data, and generating figures for the manuscript titled “Global exposure risk of frogs to increasing environmental dryness”.

GitHub Repository The Rmarkdown file can be downloaded from the Code drop down menu (top right).

Abbreviations

  • AI: Aridity Index
  • \(e_a\): actual vapour pressure
  • \(e_s\): saturation vapour pressure
  • EWL: Evaporative water loss
  • IUCN: International Union for Conservation of Nature
  • PDSI: Palmer Drought Severity Index
  • PRISMA: Preferred Reporting Items for Systematic Reviews and Meta-Analyses
  • RH: Relative humidity
  • \(r_i\): Relative skin resistance or resistance to water loss
  • SA: surface-area
  • SPP: Shared Socioeconomic Pathway
  • VPD: Vapour pressure deficit
  • WoS: Web of Science
  • WU: water uptake

Spatial risk

Descriptors

The following series of code is to estimate the risk of anuran amphibians to increasing aridity (Aridity Index; AI) and extreme drought (Palmer Drought Severity Index; PDSI). The AI was categorised to five categories (Humid, Dry sub-humid, Semi-arid, Arid, and Hyper-arid) and the PDSI was categorised to seven categories (Extremely moist, Very moist, Moderate moist, Normal, Moderate drought, Severe drought, Extreme drought) based on descriptions from Budyko (1961) and Palmer (1965), respectively (Table S1).

Generalised ecological types or ‘ecotype’ of each anuran species were classified based on descriptions from Moen and Wiens (2017) focusing on adult behaviour and microhabitat preferences outside the breeding season, given that many anurans breed in water but are not adapted to live in water all year (Table S2).

Table S1

Table S1 Aridity index (Budyko, 1961) and the Palmer Drought Severity Index (Palmer, 1965) categorised.

Aridity index (AI) AI value Palmer Drought Severity Index (PDSI) PDSI Value
Humid ≥ 0.65 Extremely moist ≥ 4
Dry sub-humid 0.50 – ≤ 0.65 Very moist 3 – ≤ 4
Semi-arid 0.20 – ≤ 0.50 Moderate moist 2 – ≤ 3
Arid 0.05 – ≤ 0.20 Normal -2 – ≤ 2
Hyper-arid < 0.05 Moderate drought -3 – ≤ -2
Severe drought -4 – ≤ -3
Extreme drought < -4

Table S2

Table S2 Microhabitat preference or ecotype (Moen and Wiens, 2017).

Ecotype Description
Aquatic Almost always in water.
Arboreal Ability to climb vegetation and spends a substantial amount of time above ground (e.g. forests, on top of vegetations in wetlands).
Semi-aquatic Stay near water bodies, usually permanent water (e.g. ground-level wetlands). Often observed in water and nearby vegetation.
Ground-dwelling Terrestrial only, not always near water bodies, however always in a moist environment (e.g. forest leaf litter, moist soils, scrublands, grassland). Sometimes above ground and sometimes semi-fossorial. Can be classified as broad.
Fossorial The non-breeding season is spent underground in burrows. Capable of burrowing and aestivating.
Stream-dwelling Restricted to near fast-flowing streams usually on rocks or vegetation near streams.

Species richness

Anuran (frogs and toads) distribution shape files were obtained from the International Union for Conservation of Nature’s Red List of Threatened Species (IUCN Red List; extracted on 11/01/2021). Species richness or species assemblages was defined as the sum of species in each grid cell (0.5°), based on the geographic range, and was calculated using the rasterizeIUCN and calcSR function from the from the rasterSp package. Ecotype-specific species richness was also calculated.

filedir <- "rasterSp/"

# Clean raw data
frog_dat <- read.csv(file.path(data_path, "anuran_species_list.csv")) %>%
    dplyr::select(genus:strategy, SVL_cm:binomial_tree_phylo) %>%
    dplyr::mutate(lnSVL = log(SVL_cm), lnMass = log(mass_g), lnArea = log(shape_area),
        IUCN = factor(IUCN, levels = c("Least Concern", "Near Threatened", "Vulnerable",
            "Endangered", "Critically Endangered", "Extinct")), order_name = factor(order_name),
        family_name = factor(family_name), ecotype = factor(ecotype)) %>%
    dplyr::filter(order_name == "ANURA" & ecotype != "" & IUCN != "" & IUCN != "Extinct") %>%
    droplevels()

# Convert shape files into rasters and save to file once (downloaded shape
# files 08/01/2020) only extracted distribution of native range anuran_rast <-
# rasterizeIUCN(dsn = paste0(filedir, 'ANURA/ANURA.shp'), resolution = 0.5,
# seasonal = c(1, 2), origin = 1, presence = c(1,2), save = TRUE, path =
# paste0(rasterSp_path))

# Calculate anuran richness and by ecotype The calcSR function uses a stepwise
# procedure to calculate the sum of species for each grid cell.
anuran_sr <- rasterSp::calcSR(species_names = frog_dat$binomial_IUCN, path = paste0(rasterSp_path))
aquatic_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Aquatic",
    "binomial_IUCN"], path = paste0(rasterSp_path))
arboreal_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Arboreal",
    "binomial_IUCN"], path = paste0(rasterSp_path))
fossorial_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Fossorial",
    "binomial_IUCN"], path = paste0(rasterSp_path))
ground_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Ground-dwelling",
    "binomial_IUCN"], path = paste0(rasterSp_path))
semi_aq_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Semi-aquatic",
    "binomial_IUCN"], path = paste0(rasterSp_path))
stream_sr <- rasterSp::calcSR(species_names = frog_dat[frog_dat$ecotype == "Stream-dwelling",
    "binomial_IUCN"], path = paste0(rasterSp_path))

# Convert raster to matrix then to data frame
anuran_sr_df <- raster::as.data.frame(raster::rasterToPoints(anuran_sr)) %>%
    dplyr::rename(species_n = layer)
aquatic_sr_df <- raster::as.data.frame(raster::rasterToPoints(aquatic_sr)) %>%
    dplyr::rename(aquatic_n = layer)
arboreal_sr_df <- raster::as.data.frame(raster::rasterToPoints(arboreal_sr)) %>%
    dplyr::rename(arboreal_n = layer)
fossorial_sr_df <- raster::as.data.frame(raster::rasterToPoints(fossorial_sr)) %>%
    dplyr::rename(fossorial_n = layer)
ground_sr_df <- raster::as.data.frame(raster::rasterToPoints(ground_sr)) %>%
    dplyr::rename(ground_n = layer)
semi_aq_sr_df <- raster::as.data.frame(raster::rasterToPoints(semi_aq_sr)) %>%
    dplyr::rename(semi_aq_n = layer)
stream_sr_df <- raster::as.data.frame(raster::rasterToPoints(stream_sr)) %>%
    dplyr::rename(stream_n = layer)

There were 5636 anuran species from the IUCN Red List available for the AI and PDSI analysis.

Calculate AI and PDSI

High resolution (~4 km2) global dataset on precipitation (mm/month) and potential evapotranspiration (mm/month) were obtained from Abatzoglou et al. (2018) under 1) the current climate (1970–2000), 2) an intermediate greenhouse gas emission scenario of +2°C (Shared Socioeconomic Pathway 2–4.5; SPP2–4.5), and 3) a high greenhouse gas emission or “business-as-usual” scenario of +4°C (SSP5–8.5) by 2080–2099 (Fig. S1a–f).

We obtained a self-calibrated PDSI with Penman–Monteith potential evapotranspiration representing the current climate (1970–2000) and an intermediate and high emission scenario by 2080–2099 (SSP2–4.5 and SSP5-8.5) from Zhao and Dai (2022). The SSP2–4.5 and SSP5–8.5 scenarios were based on the average of 25 CMIP6 models of precipitation, evapotranspiration, soil moisture, and runoff (Eyring et al., 2016), where the mean annual surface temperature is expected to increase by 2.7°C (2.1–3.5°C range) and 4.4°C (3.3–5.7°C range), respectively by 2080–2100 (IPCC, 2021).

# Import the downloaded files
ppt_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate19812010_ppt.nc")),
    anuran_sr)  # Precipitation year 1981-2010 - Pr (mm)
pet_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate19812010_pet.nc")),
    anuran_sr)  # Evapotranspiration 1981-2010 - ET0 (mm)

# +2C and +4C future scenarios
ppt_2C_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate2C_ppt.nc")),
    anuran_sr)
pet_2C_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate2C_pet.nc")),
    anuran_sr)
ppt_4C_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate4C_ppt.nc")),
    anuran_sr)
pet_4C_rast <- raster::projectRaster(raster::stack(x = file.path(spatial_path, "TerraClimate4C_pet.nc")),
    anuran_sr)

# Obtain mean values from 1981-2010
ppt_mean_rast <- raster::calc(ppt_rast, fun = mean, na.rm = TRUE)
pet_mean_rast <- raster::calc(pet_rast, fun = mean, na.rm = TRUE)
ppt_2C_mean_rast <- raster::calc(ppt_2C_rast, fun = mean, na.rm = TRUE)
pet_2C_mean_rast <- raster::calc(pet_2C_rast, fun = mean, na.rm = TRUE)
ppt_4C_mean_rast <- raster::calc(ppt_4C_rast, fun = mean, na.rm = TRUE)
pet_4C_mean_rast <- raster::calc(pet_4C_rast, fun = mean, na.rm = TRUE)

# Obtain mean values from 10-year monthly PDSI
PDSI_ssp245_rast <- raster::stack(x = file.path(spatial_path, "pdsisc.monthly.1900-2100.r2.5x2.5.EnsAvg25Models.TP2.ipe-2.ssp245.nc"))
PDSI_ssp585_rast <- raster::stack(x = file.path(spatial_path, "pdsisc.monthly.1900-2100.r2.5x2.5.EnsAvg25Models.TP2.ipe-2.ssp585.nc"))

PDSI_cur_rast <- raster::subset(PDSI_ssp245_rast, grep("X197.*|X198.*|X199.*", names(PDSI_ssp245_rast),
    value = T))
PDSI_2C_rast <- raster::subset(PDSI_ssp245_rast, grep("X207.*|X208.*|X209.*", names(PDSI_ssp245_rast),
    value = T))
PDSI_4C_rast <- raster::subset(PDSI_ssp585_rast, grep("X207.*|X208.*|X209.*", names(PDSI_ssp585_rast),
    value = T))

PDSI_cur_mean_rast <- raster::calc(PDSI_cur_rast, fun = mean, na.rm = TRUE)
PDSI_2C_mean_rast <- raster::calc(PDSI_2C_rast, fun = mean, na.rm = TRUE)
PDSI_4C_mean_rast <- raster::calc(PDSI_4C_rast, fun = mean, na.rm = TRUE)

# Calculate aridity index [Precipitation (ppt) / Evapotranspiration (pet)]
ai_rast <- raster::overlay(x = ppt_mean_rast, y = pet_mean_rast, fun = function(x,
    y) {
    return(x/y)
})
ai_2C_rast <- raster::overlay(x = ppt_2C_mean_rast, y = pet_2C_mean_rast, fun = function(x,
    y) {
    return(x/y)
})
ai_4C_rast <- raster::overlay(x = ppt_4C_mean_rast, y = pet_4C_mean_rast, fun = function(x,
    y) {
    return(x/y)
})

# Calculate change in PDSI Reproject intensity raster to match anuran_sr
PDSI_cur_mean_rast <- raster::projectRaster(PDSI_cur_mean_rast, anuran_sr)
PDSI_2C_mean_rast <- raster::projectRaster(PDSI_2C_mean_rast, anuran_sr)
PDSI_4C_mean_rast <- raster::projectRaster(PDSI_4C_mean_rast, anuran_sr)

PDSI_2C_diff_rast <- raster::overlay(x = PDSI_cur_mean_rast, y = PDSI_2C_mean_rast,
    fun = function(x, y) {
        return(y - x)
    })
PDSI_4C_diff_rast <- raster::overlay(x = PDSI_cur_mean_rast, y = PDSI_4C_mean_rast,
    fun = function(x, y) {
        return(y - x)
    })

# Convert raster to matrix then to data frame
ai_df <- raster::as.data.frame(raster::rasterToPoints(ai_rast))
ai_2C_df <- raster::as.data.frame(raster::rasterToPoints(ai_2C_rast))
ai_4C_df <- raster::as.data.frame(raster::rasterToPoints(ai_4C_rast))

PDSI_2C_diff_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_2C_diff_rast))
PDSI_4C_diff_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_4C_diff_rast))

# Convert aridity index into category
ai_df <- ai_df %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

ai_2C_df <- ai_2C_df %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

ai_4C_df <- ai_4C_df %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

# Convert PDSI to category
PDSI_2C_diff_df <- PDSI_2C_diff_df %>%
    # Recode
dplyr::mutate(change_2C = case_when(layer >= 4 ~ "4", layer >= 3 & layer < 4 ~ "3",
    layer >= 2 & layer < 3 ~ "2", layer >= 1 & layer < 2 ~ "1", layer >= -1 & layer <
        1 ~ "0", layer >= -2 & layer < -1 ~ "-1", layer >= -3 & layer < -2 ~ "-2",
    layer >= -4 & layer < -3 ~ "-3", layer < -4 ~ "-4")) %>%
    # Convert to ordered factor
dplyr::mutate(change_2C = factor(change_2C, levels = c("-4", "-3", "-2", "-1", "0",
    "1", "2", "3", "4"), ordered = TRUE))

PDSI_4C_diff_df <- PDSI_4C_diff_df %>%
    # Recode
dplyr::mutate(change_4C = case_when(layer >= 4 ~ "4", layer >= 3 & layer < 4 ~ "3",
    layer >= 2 & layer < 3 ~ "2", layer >= 1 & layer < 2 ~ "1", layer >= -1 & layer <
        1 ~ "0", layer >= -2 & layer < -1 ~ "-1", layer >= -3 & layer < -2 ~ "-2",
    layer >= -4 & layer < -3 ~ "-3", layer < -4 ~ "-4")) %>%
    # Convert to ordered factor
dplyr::mutate(change_4C = factor(change_4C, levels = c("-4", "-3", "-2", "-1", "0",
    "1", "2", "3", "4"), ordered = TRUE))
# Crop and mask
world <- rgdal::readOGR(file.path(spatial_path, "ne_50m_land/ne_50m_land.shp"))
## OGR data source with driver: ESRI Shapefile 
## Source: "/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/ne_50m_land/ne_50m_land.shp", layer: "ne_50m_land"
## with 1420 features
## It has 3 fields
## Integer64 fields read as strings:  scalerank
world_spdf <- sp::SpatialPolygonsDataFrame(world, world@data)

# Precipitation
ppt_curr_plot <- raster::as.data.frame(raster::rasterToPoints(ppt_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "YlGnBu", lim = c(0, 650), name = "Precipitation (mm)") +
    ggtitle("Current (1981-2010)") + scale_y_continuous(limits = c(-60, 90), expand = c(0,
    0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0, 0)) + guides(fill = guide_colourbar(barwidth = 10,
    barheight = 0.3, label.position = "bottom")) + theme_void() + ylab(NULL) + xlab(NULL) +
    theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
        plot.title = element_text(size = 10), legend.title = element_text(size = 8),
        legend.position = "bottom") + coord_fixed(ratio = 1)

ppt_2C_plot <- raster::as.data.frame(raster::rasterToPoints(ppt_2C_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "YlGnBu", lim = c(0, 650)) + ggtitle("+2°C (2080-2100)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

ppt_4C_plot <- raster::as.data.frame(raster::rasterToPoints(ppt_4C_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "YlGnBu", lim = c(0, 650)) + ggtitle("+4°C (2080-2100)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

ppt_legend <- cowplot::get_legend(ppt_curr_plot)

ppt_prow <- cowplot::plot_grid(ppt_curr_plot + theme(legend.position = "none"), ppt_2C_plot +
    theme(legend.position = "none"), ppt_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("a", "b", "c"))

ppt_plots <- cowplot::plot_grid(ppt_prow, ppt_legend, ncol = 1, rel_heights = c(1,
    0.1))

# Evapotranspiration
pet_curr_plot <- raster::as.data.frame(raster::rasterToPoints(pet_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "Rocket", lim = c(0, 300), name = "Evapotranspiration (mm)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + guides(fill = guide_colourbar(barwidth = 10, barheight = 0.3,
    label.position = "bottom")) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10),
    legend.title = element_text(size = 8), legend.position = "bottom") + coord_fixed(ratio = 1)

pet_2C_plot <- raster::as.data.frame(raster::rasterToPoints(pet_2C_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "Rocket", lim = c(0, 300)) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

pet_4C_plot <- raster::as.data.frame(raster::rasterToPoints(pet_4C_mean_rast)) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = layer)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "Rocket", lim = c(0, 300)) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

pet_legend <- cowplot::get_legend(pet_curr_plot)

pet_prow <- cowplot::plot_grid(pet_curr_plot + theme(legend.position = "none"), pet_2C_plot +
    theme(legend.position = "none"), pet_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("d", "e", "f"))

pet_plots <- cowplot::plot_grid(pet_prow, pet_legend, ncol = 1, rel_heights = c(1,
    0.1))

# Aridity Index
arid_col <- c("#8E063B", "#CB6D53", "#E99A2C", "#F5D579", "white")
ai_curr_plot <- ggplot() + geom_raster(data = ai_df, aes(y = y, x = x, fill = category)) +
    geom_polygon(data = world_spdf, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = arid_col, guide = guide_legend(reverse = TRUE),
    name = "Aridity Index") + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10), legend.title = element_text(size = 8),
    legend.key.size = unit(0.2, "cm"), legend.position = "bottom") + coord_fixed(ratio = 1)

ai_2C_plot <- ggplot() + geom_raster(data = ai_2C_df, aes(y = y, x = x, fill = category)) +
    geom_polygon(data = world_spdf, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = arid_col, guide = guide_legend(reverse = TRUE),
    name = "Aridity Index") + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)

ai_4C_plot <- ggplot() + geom_raster(data = ai_4C_df, aes(y = y, x = x, fill = category)) +
    geom_polygon(data = world_spdf, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = arid_col, guide = guide_legend(reverse = TRUE),
    name = "Aridity Index") + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme_void() + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)

ai_legend <- cowplot::get_legend(ai_curr_plot)

ai_prow <- cowplot::plot_grid(ai_curr_plot + theme(legend.position = "none"), ai_2C_plot +
    theme(legend.position = "none"), ai_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("g", "h", "i"))

ai_plots <- cowplot::plot_grid(ai_prow, ai_legend, ncol = 1, rel_heights = c(1, 0.1))

cowplot::plot_grid(ppt_plots, pet_plots, ai_plots, ncol = 1)

Fig. S1. Climate data used to calculate the aridity index. Mean precipitation (mm) under (a) the current scenario from 1981-2010, (b) an intermediate emission scenario (Shared Socioeconomic Pathways 2 - 4.5; SSP2-4.5), and (c) a high emission scenario (SSP5-8.5) by 2080-2100. Mean potential evapotranspiration (mm) under (d) the current scenario from 1981-2010, (e) an intermediate emission scenario (SSP2-4.5), and (f) a high emission scenario (SSP5-8.5) by 2080-2100. Calculated Aridity Index for (g) the current scenario from 1981-2010, (h) an intermediate emission scenario (SSP2-4.5), and (i) a high emission scenario (SSP5-8.5) by 2080-2100.

AI risk

To examine the relationship of species richness with aridity, the number of species per gird cell was overlapped with the aridity raster layer, where each grid was assigned an AI category. The change in species richness between the current and projected (either +2 or +4 °C warming) AI category was calculated as the change in AI category grids (resolution 0.5° for decimal degree coordinates) occupied by anurans relative to the future projection. A decrease indicates reduced number of species with the assigned AI category and vice versa.

# Merge aridity index, +4C and amphibian species richness
ai_sp_df <- ai_df %>%
    dplyr::full_join(ai_2C_df, by = c("x", "y")) %>%
    dplyr::full_join(ai_4C_df, by = c("x", "y")) %>%
    dplyr::full_join(anuran_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(aquatic_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(arboreal_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(fossorial_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(ground_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(semi_aq_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(stream_sr_df, by = c("x", "y")) %>%
    dplyr::rename(aridity = layer.x, aridity_2C = layer.y, aridity_4C = layer, category = category.x,
        category_2C = category.y, category_4C = category) %>%
    drop_na(category)

# Calculate grid cells occupied for current climate
ai_sp_sum <- data.frame(ai_sp_df %>%
    dplyr::group_by(category) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(scenario = "Current", all_freq = species_n/sum(species_n) * 100,
        aquatic_freq = aquatic_n/sum(aquatic_n) * 100, arboreal_freq = arboreal_n/sum(arboreal_n) *
            100, fossorial_freq = fossorial_n/sum(fossorial_n) * 100, ground_freq = ground_n/sum(ground_n) *
            100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) * 100, stream_freq = stream_n/sum(stream_n) *
            100)

# Calculate grid cells occupied for future climate
ai_2C_sp_sum <- data.frame(ai_sp_df %>%
    dplyr::group_by(category_2C) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(scenario = "SSP245", all_freq = species_n/sum(species_n) * 100,
        aquatic_freq = aquatic_n/sum(aquatic_n) * 100, arboreal_freq = arboreal_n/sum(arboreal_n) *
            100, fossorial_freq = fossorial_n/sum(fossorial_n) * 100, ground_freq = ground_n/sum(ground_n) *
            100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) * 100, stream_freq = stream_n/sum(stream_n) *
            100) %>%
    dplyr::rename(category = category_2C)

ai_4C_sp_sum <- data.frame(ai_sp_df %>%
    dplyr::group_by(category_4C) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(scenario = "SSP585", all_freq = species_n/sum(species_n) * 100,
        aquatic_freq = aquatic_n/sum(aquatic_n) * 100, rboreal_freq = arboreal_n/sum(arboreal_n) *
            100, fossorial_freq = fossorial_n/sum(fossorial_n) * 100, ground_freq = ground_n/sum(ground_n) *
            100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) * 100, stream_freq = stream_n/sum(stream_n) *
            100) %>%
    dplyr::rename(category = category_4C)

PDSI risk

With a monthly prediction of PDSI from 1950 to 2100 globally available from Zhao and Dai (2022), we categorised future drought risk in three ways: 1) an increase in drought intensity (decrease in PDSI), an increase in drought frequency (monthly PDSI counts below -2 per year), and an increase in drought duration (number of consecutive months with PDSI values below -2). Change in drought intensity (ΔPDSI[intensity]), frequency (ΔPDSI[frequency]), and duration (ΔPDSI[duration]) under a +2 or +4 °C warming scenario (2080–2100) was calculated relative to the 1970–2000 monthly climatology per gird cell (ΔPDSI = PDSI[future] – PDSI[current]). Note, the temporal resolution was limited to monthly variation as the PDSI was developed to monitor long-term meteorological drought.

# Change in PDSI intensity
PDSI_sp_df <- anuran_sr_df %>%
    dplyr::full_join(PDSI_2C_diff_df, by = c("x", "y")) %>%
    dplyr::full_join(PDSI_4C_diff_df, by = c("x", "y")) %>%
    dplyr::full_join(aquatic_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(arboreal_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(fossorial_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(ground_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(semi_aq_sr_df, by = c("x", "y")) %>%
    dplyr::full_join(stream_sr_df, by = c("x", "y")) %>%
    dplyr::rename(PDSI_2C = layer.x, PDSI_4C = layer.y) %>%
    drop_na(change_2C) %>%
    filter(species_n != "NA")

# Calculate grid cells occupied for current climate
PDSI_sp_2C <- data.frame(PDSI_sp_df %>%
    dplyr::group_by(change_2C) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100, aquatic_freq = aquatic_n/sum(aquatic_n) *
        100, arboreal_freq = arboreal_n/sum(arboreal_n) * 100, fossorial_freq = fossorial_n/sum(fossorial_n) *
        100, ground_freq = ground_n/sum(ground_n) * 100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) *
        100, stream_freq = stream_n/sum(stream_n) * 100)

PDSI_sp_4C <- data.frame(PDSI_sp_df %>%
    dplyr::group_by(change_4C) %>%
    dplyr::summarise(species_n = length(species_n[!is.na(species_n)]), aquatic_n = length(aquatic_n[!is.na(aquatic_n)]),
        arboreal_n = length(arboreal_n[!is.na(arboreal_n)]), fossorial_n = length(fossorial_n[!is.na(fossorial_n)]),
        ground_n = length(ground_n[!is.na(ground_n)]), semi_aq_n = length(semi_aq_n[!is.na(semi_aq_n)]),
        stream_n = length(stream_n[!is.na(stream_n)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100, aquatic_freq = aquatic_n/sum(aquatic_n) *
        100, arboreal_freq = arboreal_n/sum(arboreal_n) * 100, fossorial_freq = fossorial_n/sum(fossorial_n) *
        100, ground_freq = ground_n/sum(ground_n) * 100, semi_aq_freq = semi_aq_n/sum(semi_aq_n) *
        100, stream_freq = stream_n/sum(stream_n) * 100)
# Calculate frequency of moderate to extreme drought (<-2 PDSI) per year.

# Temporal change in PDSI intensity
PDSI_2C_time_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_ssp245_rast))
PDSI_4C_time_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_ssp585_rast))

# Convert wide to long
freq_2C_df <- PDSI_2C_time_df %>%
    tidyr::pivot_longer(!c("x", "y"), names_to = "dates", values_to = "PDSI") %>%
    data.frame() %>%
    tidyr::separate(dates, c("year", "months")) %>%
    dplyr::mutate(year = as.numeric(substring(year, 2))) %>%
    dplyr::filter(year >= 1950 & year != 2100)

freq_4C_df <- PDSI_4C_time_df %>%
    tidyr::pivot_longer(!c("x", "y"), names_to = "dates", values_to = "PDSI") %>%
    data.frame() %>%
    tidyr::separate(dates, c("year", "months")) %>%
    dplyr::mutate(year = as.numeric(substring(year, 2))) %>%
    dplyr::filter(year >= 1950 & year != 2100)

# Summarise average monthly counts <-2 PDSI from 1970 to 1999 or 2080 to 2100
freq_mean_df <- freq_2C_df %>%
    dplyr::filter(year >= 1970 & year <= 1999) %>%
    dplyr::group_by(x, y, year) %>%
    dplyr::summarise(count = sum(PDSI < -2)) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_curr = mean(count))

freq_2C_diff_df <- freq_2C_df %>%
    dplyr::filter(year >= 2080 & year != 2100) %>%
    dplyr::group_by(x, y, year) %>%
    dplyr::summarise(count = sum(PDSI < -2)) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_2C = mean(count)) %>%
    dplyr::inner_join(freq_mean_df, by = c(x = "x", y = "y")) %>%
    dplyr::mutate(diff_2C = mean_2C - mean_curr)

freq_4C_diff_df <- freq_4C_df %>%
    dplyr::filter(year >= 2080 & year != 2100) %>%
    dplyr::group_by(x, y, year) %>%
    dplyr::summarise(count = sum(PDSI < -2)) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_4C = mean(count)) %>%
    dplyr::inner_join(freq_2C_diff_df, by = c(x = "x", y = "y")) %>%
    dplyr::mutate(diff_4C = mean_4C - mean_curr)
# Calculate duration of moderate to extreme drought (<-2 PDSI) from 1970 to
# 1999
dur_curr_df <- freq_2C_df %>%
    dplyr::mutate(bin = ifelse(PDSI < -2, 1, 0)) %>%
    dplyr::filter(year >= 1970 & year <= 1999) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_curr = mean(rle(bin)$lengths[rle(bin)$values == 1])) %>%
    replace(is.na(.), 0)

# Calculate duration of moderate to extreme drought (<-2 PDSI) from 2080 to
# 2100
dur_2C_df <- freq_2C_df %>%
    dplyr::mutate(bin = ifelse(PDSI < -2, 1, 0)) %>%
    dplyr::filter(year >= 2080 & year != 2100) %>%
    dplyr::group_by(x, y) %>%
    dplyr::summarise(mean_2C = mean(rle(bin)$lengths[rle(bin)$values == 1])) %>%
    replace(is.na(.), 0) %>%
    dplyr::inner_join(dur_curr_df, by = c(x = "x", y = "y")) %>%
    dplyr::mutate(diff_2C = mean_2C - mean_curr)

dur_4C_df <- freq_4C_df %>%
    dplyr::mutate(bin = ifelse(PDSI < -2, 1, 0)) %>%
    dplyr::group_by(x, y) %>%
    dplyr::filter(year >= 2080 & year != 2100) %>%
    dplyr::summarise(mean_4C = mean(rle(bin)$lengths[rle(bin)$values == 1])) %>%
    replace(is.na(.), 0) %>%
    dplyr::inner_join(dur_2C_df, by = c(x = "x", y = "y")) %>%
    dplyr::mutate(diff_4C = mean_4C - mean_curr)

The simultaneous risk of drought intensity, frequency, and duration within a grid cell that are occupied by anurans was calculated by converting each risk category as binary. Gird cells with a ΔPDSI[intensity] below -1 (indicating a decrease in PDSI) were assigned a ‘1’ binary. Both ΔPDSI[frequency] and ΔPDSI[duration] were assigned a binary of ‘1’ if the grid cell has a value of 1 month or higher (indicating increase in frequency or duration relative to current scenario). ). The number of overlapping binaries were summed up per grid cell. Therefore, a risk factor of 2 indicate species assemblages in the grid cell are at increasing risk of two drought events. We estimated which species assemblages were at risk of experiencing drought events using an arbitrary risk factor scale (species richness × drought risk), where grid cells with high drought risk and high species richness have higher “assemblage-level risk” than grid cells with high drought risk and low species richness (low assemblage-level risk).

# Intensity
names(PDSI_2C_diff_rast) <- "delta_int_2C"
names(PDSI_4C_diff_rast) <- "delta_int_4C"

# Frequency
freq_diff_rast <- rasterFromXYZ(freq_4C_diff_df) # convert to raster
crs(freq_diff_rast) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
freq_diff_rast <- projectRaster(freq_diff_rast, anuran_sr) # match anuran extent
freq_diff_df   <- raster::as.data.frame(raster::rasterToPoints(freq_diff_rast))

PDSI_freq_diff <- subset(freq_diff_rast, 4:5)
names(PDSI_freq_diff) <- c("delta_freq_2C", "delta_freq_4C")

# Duration
dur_diff_rast <- raster::rasterFromXYZ(dur_4C_df) # convert to raster
crs(dur_diff_rast) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
dur_diff_rast <- raster::projectRaster(dur_diff_rast, anuran_sr) # match anuran extent
dur_diff_df <- raster::as.data.frame(raster::rasterToPoints(dur_diff_rast))

PDSI_dur_diff  <- subset(dur_diff_rast, 4:5)
names(PDSI_dur_diff) <- c("delta_dur_2C", "delta_dur_4C")

# Combine relative PDSI metrics
PDSI_risk_comb_rast <- raster::stack(PDSI_2C_diff_rast, PDSI_4C_diff_rast, PDSI_freq_diff, PDSI_dur_diff, resample(anuran_sr, PDSI_4C_diff_rast))
                             
PDSI_risk_comb_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_risk_comb_rast)) %>%
  dplyr::rename("sp_n" = layer) %>%
  dplyr::filter(!is.na(sp_n)) %>%
  dplyr::mutate(delta_int_2C_bin = ifelse(delta_int_2C < -1, 1, 0), # delta_PDSI < -1
         delta_int_4C_bin = ifelse(delta_int_4C < -1, 1, 0), # delta_PDSI < -1
         delta_freq_2C_bin = ifelse(delta_freq_2C >1, 1, 0), # month > 1
         delta_freq_4C_bin = ifelse(delta_freq_4C >1, 1, 0), # month > 1
         delta_dur_2C_bin = ifelse(delta_dur_2C >1, 1, 0), # month > 1
         delta_dur_4C_bin = ifelse(delta_dur_4C >1, 1, 0)) %>% # month > 1 
  dplyr::rowwise() %>%
  dplyr::mutate(count_2C = sum(delta_int_2C_bin, delta_freq_2C_bin, delta_dur_2C_bin, na.rm = T),
         
         count_4C = sum(delta_int_4C_bin, delta_freq_4C_bin, delta_dur_4C_bin, na.rm = T),
         risk_2C  = sp_n * count_2C,
         risk_4C  = sp_n * count_4C,
         count_2C = factor(count_2C, levels = c("3", "2", "1")),
         count_4C = factor(count_4C, levels = c("3", "2", "1"))
         )
# Combine absolute PDSI metrics
PDSI_ab_rast <- raster::stack(PDSI_cur_mean_rast, PDSI_2C_mean_rast, PDSI_4C_mean_rast,
    freq_diff_rast, dur_diff_rast, resample(anuran_sr, PDSI_4C_mean_rast))
PDSI_ab_rast_crop <- raster::mask(crop(PDSI_ab_rast, extent(world)), world)  # crop 

PDSI_ab_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_ab_rast_crop)) %>%
    dplyr::rename(PDSI_cur = "layer.1", PDSI_2C = "layer.2", PDSI_4C = "layer.3",
        freq_cur = "mean_curr.1", freq_2C = "mean_2C.1", freq_4C = "mean_4C.1", dur_cur = "mean_curr.2",
        dur_2C = "mean_2C.2", dur_4C = "mean_4C.2", sp_n = "layer.4") %>%
    filter(sp_n != "NA")

colours_PDSI <- RColorBrewer::brewer.pal(9, "RdBu")

# Intensity
PDSI_cur_plot <- PDSI_ab_df %>%
    dplyr::mutate(PDSI_cur_cat = case_when(PDSI_cur >= 2 & PDSI_cur < 3 ~ "2", PDSI_cur >=
        1 & PDSI_cur < 2 ~ "1", PDSI_cur >= -1 & PDSI_cur < 1 ~ "0")) %>%
    dplyr::mutate(PDSI_cur_cat = factor(PDSI_cur_cat, levels = c("0", "1", "2"),
        ordered = TRUE)) %>%
    filter(PDSI_cur_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = PDSI_cur_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#F7F7F7", "#D1E5F0", "#92C5DE")) + theme_void() +
    ylab(NULL) + xlab(NULL) + ggtitle("Mean PDSI intensity (1970–2000)") + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
    plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

PDSI_2C_plot <- PDSI_ab_df %>%
    dplyr::mutate(PDSI_2C_cat = case_when(PDSI_2C >= 4 ~ "4", PDSI_2C >= 3 & PDSI_2C <
        4 ~ "3", PDSI_2C >= 2 & PDSI_2C < 3 ~ "2", PDSI_2C >= 1 & PDSI_2C < 2 ~ "1",
        PDSI_2C >= -1 & PDSI_2C < 1 ~ "0", PDSI_2C >= -2 & PDSI_2C < -1 ~ "-1", PDSI_2C >=
            -3 & PDSI_2C < -2 ~ "-2", PDSI_2C >= -4 & PDSI_2C < -3 ~ "-3", PDSI_2C <
            -4 ~ "-4")) %>%
    dplyr::mutate(PDSI_2C_cat = factor(PDSI_2C_cat, levels = c("-4", "-3", "-2",
        "-1", "0", "1", "2", "3", "4"), ordered = TRUE)) %>%
    filter(PDSI_2C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = PDSI_2C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = colours_PDSI) + theme_void() + ylab(NULL) + xlab(NULL) +
    ggtitle("Mean PDSI intensity (+2°C)") + scale_y_continuous(limits = c(-60, 90),
    expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0, 0)) +
    theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

PDSI_4C_plot <- PDSI_ab_df %>%
    dplyr::mutate(PDSI_4C_cat = case_when(PDSI_4C >= 4 ~ "4", PDSI_4C >= 3 & PDSI_4C <
        4 ~ "3", PDSI_4C >= 2 & PDSI_4C < 3 ~ "2", PDSI_4C >= 1 & PDSI_4C < 2 ~ "1",
        PDSI_4C >= -1 & PDSI_4C < 1 ~ "0", PDSI_4C >= -2 & PDSI_4C < -1 ~ "-1", PDSI_4C >=
            -3 & PDSI_4C < -2 ~ "-2", PDSI_4C >= -4 & PDSI_4C < -3 ~ "-3", PDSI_4C <
            -4 ~ "-4")) %>%
    dplyr::mutate(PDSI_4C_cat = factor(PDSI_4C_cat, levels = c("-4", "-3", "-2",
        "-1", "0", "1", "2", "3", "4"), ordered = TRUE)) %>%
    filter(PDSI_4C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = PDSI_4C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = colours_PDSI, name = "PDSI", guide = guide_legend(reverse = TRUE,
        nrow = 1)) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean PDSI intensity (+4°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10), legend.title = element_text(size = 8),
    legend.key.height = unit(0.2, "cm"), legend.key.width = unit(0.2, "cm"), legend.position = "bottom") +
    coord_fixed(ratio = 1)  # fixed ratio

int_legend <- cowplot::get_legend(PDSI_4C_plot)

int_prow <- cowplot::plot_grid(PDSI_cur_plot + theme(legend.position = "none"), PDSI_2C_plot +
    theme(legend.position = "none"), PDSI_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("a", "b", "c"))

int_plots <- cowplot::plot_grid(int_prow, int_legend, ncol = 1, rel_heights = c(1,
    0.1))

# Frequency
freq_cur_plot <- PDSI_ab_df %>%
    dplyr::mutate(freq_cur_cat = case_when(freq_cur > 0.1 & freq_cur < 1 ~ "<1")) %>%
    filter(freq_cur_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = freq_cur_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = "#ededed") + theme_void() + ylab(NULL) + xlab(NULL) +
    ggtitle("Mean drought frequency (1970–2000)") + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
    plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

freq_2C_plot <- PDSI_ab_df %>%
    dplyr::mutate(freq_2C_cat = case_when(freq_2C >= 10 ~ "10-12", freq_2C >= 8 &
        freq_2C < 10 ~ "8-10", freq_2C >= 6 & freq_2C < 8 ~ "6-8", freq_2C >= 4 &
        freq_2C < 6 ~ "4-6", freq_2C >= 2 & freq_2C < 4 ~ "2-4", freq_2C >= 1 & freq_2C <
        2 ~ "1-2", freq_2C > 0.1 & freq_2C < 1 ~ "<1")) %>%
    dplyr::mutate(freq_2C_cat = factor(freq_2C_cat, levels = c("10-12", "8-10", "6-8",
        "4-6", "2-4", "1-2", "<1"), ordered = TRUE)) %>%
    filter(freq_2C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = freq_2C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7")) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean drought frequency (+2°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

freq_4C_plot <- PDSI_ab_df %>%
    dplyr::mutate(freq_4C_cat = case_when(freq_4C >= 10 ~ "10-12", freq_4C >= 8 &
        freq_4C < 10 ~ "8-10", freq_4C >= 6 & freq_4C < 8 ~ "6-8", freq_4C >= 4 &
        freq_4C < 6 ~ "4-6", freq_4C >= 2 & freq_4C < 4 ~ "2-4", freq_4C >= 1 & freq_4C <
        2 ~ "1-2", freq_4C > 0.1 & freq_4C < 1 ~ "<1")) %>%
    dplyr::mutate(freq_4C_cat = factor(freq_4C_cat, levels = c("10-12", "8-10", "6-8",
        "4-6", "2-4", "1-2", "<1"), ordered = TRUE)) %>%
    filter(freq_4C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = freq_4C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7"), name = "Months", guide = guide_legend(reverse = TRUE,
        nrow = 1)) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean drought frequency (+4°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10), legend.title = element_text(size = 8),
    legend.key.height = unit(0.2, "cm"), legend.key.width = unit(0.2, "cm"), legend.position = "bottom") +
    coord_fixed(ratio = 1)  # fixed ratio

freq_legend <- cowplot::get_legend(freq_4C_plot)

freq_prow <- cowplot::plot_grid(freq_cur_plot + theme(legend.position = "none"),
    freq_2C_plot + theme(legend.position = "none"), freq_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("d", "e", "f"))

freq_plots <- cowplot::plot_grid(freq_prow, freq_legend, ncol = 1, rel_heights = c(1,
    0.1))


# Duration
dur_cur_plot <- PDSI_ab_df %>%
    dplyr::mutate(dur_cur_cat = case_when(dur_cur >= 2 & dur_cur < 4 ~ "2-4", dur_cur >=
        1 & dur_cur < 2 ~ "1-2", dur_cur > 0.1 & dur_cur < 1 ~ "<1")) %>%
    dplyr::mutate(dur_cur_cat = factor(dur_cur_cat, levels = c("2-4", "1-2", "<1"),
        ordered = TRUE)) %>%
    filter(dur_cur_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = dur_cur_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#FDDBC7", "#FAE9DF", "#F7F7F7")) + theme_void() +
    ylab(NULL) + xlab(NULL) + ggtitle("Mean drought duration (1970–2000)") + scale_y_continuous(limits = c(-60,
    90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180, 180), expand = c(0,
    0)) + theme(axis.title = element_blank(), axis.text = element_blank(), axis.ticks = element_blank(),
    plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

dur_2C_plot <- PDSI_ab_df %>%
    dplyr::mutate(dur_2C_cat = case_when(dur_2C >= 10 ~ ">10", dur_2C >= 8 & dur_2C <
        10 ~ "8-10", dur_2C >= 6 & dur_2C < 8 ~ "6-8", dur_2C >= 4 & dur_2C < 6 ~
        "4-6", dur_2C >= 2 & dur_2C < 4 ~ "2-4", dur_2C >= 1 & dur_2C < 2 ~ "1-2",
        dur_2C > 0.1 & dur_2C < 1 ~ "<1")) %>%
    dplyr::mutate(dur_2C_cat = factor(dur_2C_cat, levels = c(">10", "8-10", "6-8",
        "4-6", "2-4", "1-2", "<1"), ordered = TRUE)) %>%
    filter(dur_2C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = dur_2C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7")) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean drought duration (+2°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

dur_4C_plot <- PDSI_ab_df %>%
    dplyr::mutate(dur_4C_cat = case_when(dur_4C >= 10 ~ ">10", dur_4C >= 8 & dur_4C <
        10 ~ "8-10", dur_4C >= 6 & dur_4C < 8 ~ "6-8", dur_4C >= 4 & dur_4C < 6 ~
        "4-6", dur_4C >= 2 & dur_4C < 4 ~ "2-4", dur_4C >= 1 & dur_4C < 4 ~ "1-2",
        dur_4C > 0.1 & dur_4C < 1 ~ "<1")) %>%
    dplyr::mutate(dur_4C_cat = factor(dur_4C_cat, levels = c(">10", "8-10", "6-8",
        "4-6", "2-4", "1-2", "<1"), ordered = TRUE)) %>%
    filter(dur_4C_cat != "NA") %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = dur_4C_cat)) + geom_polygon(data = world_spdf,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7"), name = "Months", guide = guide_legend(reverse = TRUE,
        nrow = 1)) + theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Mean drought duration (+4°C)") +
    scale_y_continuous(limits = c(-60, 90), expand = c(0, 0)) + scale_x_continuous(limits = c(-180,
    180), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10), legend.title = element_text(size = 8),
    legend.key.size = unit(0.2, "cm"), legend.position = "bottom") + coord_fixed(ratio = 1)  # fixed ratio

dur_legend <- cowplot::get_legend(dur_4C_plot)

dur_prow <- cowplot::plot_grid(dur_cur_plot + theme(legend.position = "none"), dur_2C_plot +
    theme(legend.position = "none"), dur_4C_plot + theme(legend.position = "none"),
    align = "v", ncol = 3, labels = c("g", "h", "i"))

dur_plots <- cowplot::plot_grid(dur_prow, dur_legend, ncol = 1, rel_heights = c(1,
    0.1))


cowplot::plot_grid(int_plots, freq_plots, dur_plots, ncol = 1)

Fig. S2. Mean monthly Palmer Drought Severity Index (PDSI) self-calibrated with Penman–Monteith potential evapotranspiration from (a) 1970–2000, and from 2080-2100 under (b) under an intermediate emission scenario (Shared Socioeconomic Pathways 2 - 4.5; SSP2-4.5), and (c) under a high emission scenario (SSP5-8.5). Mean yearly frequency of moderate to extreme drought (PDSI < -2) from (d) 1970–2000, and from 2080-2100 (e) under an intermediate emission scenario (SSP2-4.5), and (f) under a high emission scenario (SSP5-8.5). Mean duration of moderate to extreme drought (PDSI < -2) from (g) 1970–2000, and from 2080-2100 (h) under an intermediate emission scenario (SSP2-4.5), and (i) under a high emission scenario (SSP5-8.5).

Summary

Ecotype AI distribution

Mean ± s.d. aridity index occupied by different anuran ecotypes.

Ecotype AI (mean ± s.d.)
Stream-dwelling 1.46 ± 0.62
Arboreal 1.01 ± 0.62
Semi-aquatic 1.01 ± 0.58
Aquatic 0.98 ± 0.61
Ground-dwelling 0.89 ± 0.64
Fossorial 0.80 ± 0.61

2°C AI risk

Percent change in aridity by 2080–2100 (+ 2°C) relative to current climate (1981–2010) for all anurans and also by ecotype.

Ecotype All (%) Aquatic 2°C (%) Arboreal 2°C (%) Fossorial 2°C(%) Ground-dwelling 2°C (%) Semi-aquatic 2°C (%) Stream-dwelling 2°C (%)
Hyper-arid -2.3 13.1 -15.2 -37.25 -2.0 4.7 -18.2
Arid 5.0 10.2 6.3 9.90 4.9 10.0 26.8
Semi-arid 1.4 2.1 1.5 0.75 1.6 1.1 13.9
Dry sub-humid 2.5 11.1 9.5 -3.67 8.4 2.8 10.4
Humid -1.4 -3.2 -2.2 -2.00 -2.4 -1.3 -1.3

4°C AI risk

Percent change in aridity by 2080–2100 (+ 4°C) relative to current climate (1981–2010) for all anurans and also by ecotype.

Ecotype All (%) Aquatic 2°C (%) Arboreal 2°C (%) Fossorial 2°C(%) Ground-dwelling 2°C (%) Semi-aquatic 2°C (%) Stream-dwelling 2°C (%)
Hyper-arid 3.0 28.3 -4.3 -13.7 3.1 11.6 -9.1
Arid 13.2 33.0 20.6 23.1 13.5 27.0 43.7
Semi-arid 8.4 11.6 14.3 4.5 8.8 10.8 53.8
Dry sub-humid 9.0 25.2 16.6 -3.5 16.0 11.6 23.9
Humid -5.8 -9.8 -7.6 -7.5 -7.6 -5.7 -3.8

2°C PDSI risk

Percent change in drought intensity (ΔPDSI), drought frequency (ΔFrequency), and drought duration (ΔDuration) by 2080–2099 (+ 2°C scenario) relative to current climate (1970–2000) in grid cells occupied by anurans and also by ecotype.

ΔPDSI All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
-4 0.01 0.00 0.00 0.00 0.00 0.01 0.00
-3 0.15 0.00 0.00 0.00 0.06 0.19 0.00
-2 2.00 4.22 3.35 4.35 2.18 2.46 5.48
-1 18.55 33.52 28.74 27.06 20.99 21.74 26.88
0 71.05 54.90 55.68 54.07 68.60 66.72 60.07
1 6.40 5.19 8.86 9.94 6.05 6.84 6.19
2 1.59 1.83 2.90 3.99 1.84 1.74 1.23
3 0.25 0.34 0.48 0.59 0.29 0.30 0.14
ΔFrequency (months) All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
10-12 0.14 0.00 0.00 0.00 0.05 0.17 0.00
8-10 0.22 0.03 0.06 0.03 0.18 0.25 0.20
6-8 0.61 0.78 0.70 0.79 0.60 0.70 0.86
4-6 2.15 3.86 3.40 3.01 2.33 2.26 3.71
2-4 12.25 21.14 19.23 16.82 13.42 13.75 26.57
1-2 16.90 24.28 17.56 18.39 18.51 18.26 10.49
0-1 56.26 42.56 46.21 46.64 53.17 54.34 48.46
-0-1 11.45 7.36 12.84 14.32 11.73 10.27 9.72
ΔDuration (months) All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
>10 0.27 0.00 0.00 0.00 0.10 0.34 0.00
8-10 0.06 0.00 0.00 0.00 0.04 0.06 0.01
6-8 0.11 0.00 0.00 0.00 0.09 0.11 0.07
4-6 0.47 0.67 0.61 0.75 0.48 0.55 0.57
2-4 7.79 14.23 11.94 10.29 8.61 9.21 15.78
1-2 38.11 34.96 29.11 23.85 38.14 39.87 27.17
0-1 39.57 41.03 42.90 47.79 38.34 37.31 44.53
-0-1 12.98 8.46 14.49 16.04 13.47 11.90 11.82
-1-2 0.64 0.65 0.95 1.28 0.71 0.64 0.04

4°C PDSI risk

Percent change in drought intensity (ΔPDSI), frequency (ΔFrequency), and duration (ΔDuration) by 2080–2099 (+ 4°C scenario) relative to current climate (1970–2000) in grid cells occupied by anurans and by ecotype.

ΔPDSI All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
-4 0.83 1.3 0.96 1.3 0.74 1.0 1.9
-3 4.44 9.9 7.80 9.6 5.04 5.4 15.2
-2 10.88 17.7 16.15 11.0 12.26 12.6 14.4
-1 22.33 26.6 19.04 25.3 24.78 23.6 12.2
0 44.62 31.9 37.41 32.8 42.33 40.2 41.6
1 9.63 4.5 6.79 5.6 6.97 9.5 6.8
2 2.94 2.2 4.17 4.3 2.87 2.9 3.4
3 1.39 1.9 2.30 2.4 1.60 1.4 1.9
4 2.94 3.9 5.38 7.7 3.41 3.4 2.5
ΔFrequency (months) All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
10-12 1.6 2.2 1.9 2.0 1.6 1.9 2.9
8-10 4.9 9.3 7.7 7.3 5.4 5.3 11.6
6-8 7.0 10.9 10.0 8.4 7.8 7.5 11.9
4-6 14.0 17.1 13.2 9.9 15.7 15.4 10.7
2-4 22.8 22.8 17.9 25.1 24.1 22.9 12.4
1-2 12.1 11.2 12.9 12.1 11.4 11.4 16.2
0-1 30.1 20.3 26.5 22.8 25.6 28.4 29.4
-0-1 7.6 6.2 9.8 12.3 8.4 7.2 4.8
ΔDuration (months) All (%) Aquatic (%) Arboreal (%) Fossorial (%) Ground-dwelling (%) Semi-aquatic (%) Stream-dwelling (%)
>10 2.53 2.8 2.6 2.6 2.46 2.84 3.90
8-10 1.02 2.0 1.6 1.6 1.14 1.14 2.16
6-8 2.33 4.0 3.7 3.1 2.60 2.50 4.47
4-6 11.07 16.6 13.5 9.0 12.48 12.55 14.75
2-4 24.82 23.0 19.5 18.4 26.38 26.19 17.99
1-2 23.42 22.9 20.5 23.1 20.52 22.95 19.89
0-1 25.18 21.7 26.0 26.7 23.70 22.79 29.51
-0-1 8.83 5.8 11.0 13.5 9.79 8.12 7.27
-1-2 0.81 1.2 1.4 1.9 0.93 0.93 0.05

Dataset

Load and clean the raw dataset raw_data.csv.

# Load and clean raw data
raw_dat <- read.csv(file.path(data_path, "raw_data.csv")) %>%
  dplyr::select(study_ID:unit, r_s_est, calculated) %>%
  dplyr::mutate(ecotype  = factor(ecotype),
         family   = factor(family),
         origin   = factor(origin),
         strategy = factor(case_when(strategy == "" ~ "none", TRUE ~ as.character(strategy))),
         strategy = fct_relevel(strategy, "none", "water-proof", "cocoon", "hollow"),
         trait    = factor(trait),
         response = factor(response),
         lnMass   = log(mean_mass_g),
         lnFlow   = log(airflow_cm_s + 1),
         es_kPa   = ifelse(trait == "water loss", 0.611 * exp(2500000 / 461.5 * (1 / 273 - 1 / (trt_temp + 273.15))), NA), # saturation vapor pressure (kPa) at a given temperature
         ea_kPa   = ifelse(trait == "water loss", RH_perc * es_kPa / 100, NA), # actual vapor pressure (kPa)
         VPD_kPa  = es_kPa - ea_kPa,
         lnVPD    = log(VPD_kPa)) %>%
  dplyr::filter(species_phylo != "") # remove rows with no species

ewl_dat <- raw_dat %>%
  dplyr::filter(response == "evaporative water loss" & !is.na(unit_corrected_mean)) %>%
  dplyr::mutate(mg_h_mean = unit_corrected_mean * dors_SA_cm2,
                mg_h_sd   = unit_corrected_sd * dors_SA_cm2,    
                lnMean    = log(mg_h_mean),
                v         = mg_h_sd^2 / sample_size, # sampling variance (v)
                sei       = sqrt(v), # standard error (SE)
                inv       = 1 / sei, # precision (inverse of SE) )
                w         = 1 / v, # weight (inverse of variance) 
                h_70      = (mean_mass_g - (mean_mass_g * 0.7)) / (mg_h_mean * 0.001)) 

resist_dat <- raw_dat %>%
  dplyr::filter(!is.na(r_s_est)) %>%
  dplyr::mutate(lnMean = log(r_s_est + 1))

wu_dat <- raw_dat %>%
  dplyr::filter(trait == "water gain" & !is.na(unit_corrected_mean)) %>%
  dplyr::mutate(mg_h_mean = unit_corrected_mean * vent_SA_cm2,
                mg_h_sd   = unit_corrected_sd * vent_SA_cm2,
                lnMean    = log(mg_h_mean),
                v         = mg_h_sd^2 / sample_size, # sampling variance (v)
                sei       = sqrt(v), # standard error (SE)
                inv       = 1 / sei) # precision (inverse of SE)

#ewl_dat %>%
  #group_by(strategy) %>%
  #summarise(mean = mean(h_70, na.rm = TRUE))

There are 238 species with data on evaporative water loss (102 studies), 224 species with skin resistance data (81 studies), and 121 species with water uptake data (51 studies). We used the evaporative water loss to analyse differences between ecotype as there are more species represented compared to the skin resistance data. There were three species that were excluded from the analysis because they were not listed in the IUCN Red List and were not present in the phylogenetic tree from Jetz and Pyron (2018): Brachycephalus pitanga, Elachistocleis cesarii, and Leptodactylus luctator.

Geographical bias in hydroregulation studies

Fig. S4. Spatial distribution of hydroregulation studies using wild caught anurans (study n = 113). 19 studies used captive raised anurans. There are large regions around central Africa and Eurasia with high amphibian diversity, but no hydrological studies conducted (Fig. 1b).


Prepare phylogeny for analysis

The phylogeny was obtained from Jetz and Pyron (2018) comprising of 7,238 species. The tree was pruned to match the 256 species extracted for the subsequent analysis.

# Load tree
phylo_tree <- ape::read.tree(file.path(data_path, "amph_shl_new_Consensus_7238.tre"))

# Pruning data and phylogeny
tree_tip_label <- phylo_tree$tip.label  # extract tree tip names
sp_list <- raw_dat$species_phylo  # extract species name from mean data
pruned_tree <- ape::drop.tip(phylo_tree, setdiff(phylo_tree$tip.label, sp_list))  # prune phylo_tree to keep species from the raw data
pruned_tree <- phytools::force.ultrametric(pruned_tree, method = "extend")  # ultrametricize the tree
phylo_cor <- vcv(pruned_tree, cor = T)

setdiff(raw_dat$species_phylo, rownames(phylo_cor))
setdiff(rownames(phylo_cor), raw_dat$species_phylo)

# ape::is.ultrametric(pruned_tree)

Analysis

The original model incorporated origin (lab-raised or wild-caught) and whether the bladder was void of urine prior to the experiment. However, the model’s bulk effective samples size (ESS) was too low, indicating posterior means and medians may be unreliable. Since origin and whether the bladder was emptied did not influence \(r_i\), they were excluded in the final model. For transparency, on average, wild-caught anurans had, on average, higher \(r_i\) relative to lab-raised anurans (0.08 [-0.47:0.31]), and anurans with their bladder voided of urine had higher \(r_i\) (0.17 [-0.59: 0.25]). However there is substantial variability between the wild-caught and lab-raised groups, and whether anurans with their bladder voided or not.

# options(brms.backend = 'cmdstanr') # Error from using Rstans 'error in
# unserialize(socklist[[n]]) : error reading from connection'. Used cmdstanr
# around it.

priors <- c(prior(normal(0, 3), "b"), prior(normal(0, 3), "Intercept"), prior(student_t(3,
    0, 10), "sd"), prior(student_t(3, 0, 10), "sigma"))

ri_model <- brms::brm(lnMean ~ ecotype + strategy + lnMass + lnVPD + lnFlow + (1 |
    study_ID) + (1 + lnMass | species_iucn) + (1 | gr(species_phylo, cov = phylo)),
    data = resist_dat, family = gaussian(), data2 = list(phylo = phylo_cor), prior = priors,
    chains = 4, cores = 4, iter = 5000, warmup = 2500, control = list(adapt_delta = 0.99,
        max_treedepth = 15))

wu_model <- brms::brm(lnMean ~ ecotype + lnMass + trt_temp + hydration + origin +
    (1 | study_ID) + (1 + lnMass | species_iucn) + (1 | gr(species_phylo, cov = phylo)),
    data = wu_dat %>%
        dplyr::group_by(ecotype) %>%
        dplyr::filter(n() >= 5), family = gaussian(), data2 = list(phylo = phylo_cor),
    prior = priors, chains = 4, cores = 4, iter = 5000, warmup = 2500, control = list(adapt_delta = 0.99,
        max_treedepth = 15))

Fig. S5. Scatterplots of the observed data (y) vs the average simulated data (yrep) from the posterior predictive distribution for the (a) resistance to water loss model, and (b) the water uptake model. Dashed line represents a slope of 1.

Model output

Table S3 - \(r_i\) model

Table S3. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the \(r_i\) model, which includes the intercept (\(\beta_0\)), ecotype, strategy, the natural logarithm of body mass (lnMass), the natural logarithm of vapour pressure deficit (lnVPD), and the natural logarithm of the experimental flow rate (lnFlow). Group-level effects include the standard deviations (\(\sigma\)) for study-level observations (\(\sigma_{study}^2\)), phylogenetic relatedness (\(\sigma_{phylogeny}^2\)), and the correlation among species (\(\sigma_{species}^2\)) and body mass (\(\sigma_{lnMass}^2\)). \(R_{marginal}^2\) represents the variance explained by fixed effects, while \(R_{conditional}^2\) represents the variance explained by both fixed effects and group-level effects.

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
ln\(\beta_0\) 1.12 0.53 0.08 2.17
Arboreal 0.71 0.53 -0.35 1.75
Fossorial 0.03 0.53 -1.03 1.06
Ground-dwelling 0.13 0.52 -0.92 1.15
Semi-aquatic -0.04 0.53 -1.10 1.00
Stream-dwelling 0.00 0.57 -1.13 1.10
Water-proof 1.87 0.17 1.53 2.21
Cocoon 3.03 0.14 2.76 3.30
Hollow 1.65 0.43 0.80 2.48
lnMass 0.10 0.03 0.04 0.17
lnVPD -0.01 0.05 -0.10 0.09
lnFlow -0.22 0.06 -0.34 -0.10
Group-level effects
\(\sigma_{species}^2\) 0.35 0.12 0.07 0.57
\(\sigma_{lnMass}^2\) 0.11 0.05 0.01 0.19
cor(\(\sigma_{species}^2\), \(\sigma_{lnMass}^2\)) -0.58 0.42 -0.98 0.68
\(\sigma_{phylogeny}^2\) 0.36 0.13 0.09 0.61
\(\sigma_{study}^2\) 0.83 0.09 0.67 1.01
Phylogenetic signal
\(\lambda\) 0.38 0.16 0.04 0.65
Variance
\(R_{marginal}^2\) 64.06 59.74 67.84
\(R_{conditional}^2\) 89.04 86.91 90.81

Table S4 - WU model

Table S4. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the water uptake model, which includes the intercept (\(\beta_0\)), ecotype, the natural logarithm of body mass (lnMass), treatment temperature, initial hydration level, and origin (lab-raised or wild caught). Group-level effects include the standard deviations (\(\sigma\)) for study-level observations (\(\sigma_{study}^2\)), phylogenetic relatedness (\(\sigma_{phylogeny}^2\)), and the correlation among species (\(\sigma_{species}^2\)) and body mass (\(\sigma_{lnMass}^2\)). \(R_{marginal}^2\) represents the variance explained by fixed effects, while \(R_{conditional}^2\) represents the variance explained by both fixed effects and group-level effects.

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
ln\(\beta_0\) 8.93 0.85 7.25 10.60
Fossorial -0.43 0.28 -0.99 0.13
Ground-dwelling -0.18 0.22 -0.62 0.24
Semi-aquatic -0.17 0.29 -0.73 0.39
ecotypeStream-dwelling -0.61 0.31 -1.22 -0.01
lnMass 0.80 0.05 0.70 0.90
Treatment temperature 0.01 0.01 -0.01 0.04
Initial hydration -0.05 0.01 -0.07 -0.04
Origin - Wild 0.02 0.43 -0.82 0.88
Group-level effects
\(\sigma_{species}^2\) 0.24 0.14 0.01 0.52
\(\sigma_{lnMass}^2\) 0.10 0.05 0.01 0.20
cor(\(\sigma_{species}^2\), \(\sigma_{lnMass}^2\)) 0.09 0.53 -0.90 0.95
\(\sigma_{phylogeny}^2\) 0.58 0.20 0.15 0.96
\(\sigma_{study}^2\) 1.03 0.13 0.80 1.32
Phylogenetic signal
\(\lambda\) 0.77 0.17 0.21 0.94
Variance
\(R_{marginal}^2\) 69.74 62.47 74.80
\(R_{conditional}^2\) 97.70 96.53 98.58

Fig. S6 - \(r_i\) model

Fig. S6. Differences in resistance to water loss, \(r_i\) (s cm-1) by (a) ecotype and (b) water-conserving strategies. Note, when plotting by ecotype, the \(r_i\) excludes behavioural water-conserving strategies such as during cocoon-forming and inside hollows. Mean estimates ± 95% CI presented in black points and error bars, while raw values were presented as grey points.


Fig. S7 - WU model

Fig. S7. Differences in cutaneous water uptake (mg H2O h-1) by ecotype. Mean estimates ± 95% CI presented in black points and error bars, while raw values were presented as grey points. The size of the grey points indicates study precision (inverse of standard error).


NicheMapR

To estimate the influence of warming and drought on activity of a hypothetical frog, we simulated a water and heat energy exchange model (Fig. S8a) and its interaction with a simulated local microclimate using the NicheMapR package (Kearney and Porter, 2017; Kearney and Porter, 2020).

Fig. S8. Summary water and energy exchange model from Tracy (1976) integrated into NicheMapR and water conserving strategies. (a) Schematic summary of the exchanges of energy and water between a frog and its environment used to develop the transient-state model of water exchange. In respect to water exchange, the net water loss represents water loss from respiratory, cutaneous, ocular, and cloaca evaporation as well as urinary and faecal water (Pirtle et al., 2019). (b) Behavioural, morphological, and physiological strategies employed by frogs on land to reduce water loss (Hillman et al., 2009).

Simulate water-conserving behaviours

We used the modularized version of NicheMapR’s v3.2.1 ectotherm model (i.e. ectoR_devel) and coded behavioral functions to account for the influence of hydration on activity (behav_functions function) which can be found in the behav_functions.R file on GitHub.

When the animal is not active (i.e. is below ground), it is simulated to go to an underground retreat. It selects the shallowest depth with temperatures between Tmax and Tmin. If water = T, the frog selects the shallowest node with temperatures between Tmax and Tmin and a water potential >= -72.5, which was reported as a soil water potential from which Rana pipiens could absorb water. When the animal is belowground, it re-hydrates if the soil water potential is >= -72.5, at a rate specified in hyd.rate and proportional to the level of dehydration, following:

\[\begin{equation} \frac{Hyd_{max} - Hyd_{i}}{Hyd_{max}} \times hyd.rate, \tag{16} \end{equation}\]

It is important to note that currently frogs are not re-hydrating when active aboveground.

The “skinwet” term (\(p_{wet}\)) determines the proportion of the total surface area used in the calculation of mass transfer of water from the surface. Here, \(p_{wet}\) was calculated from empirically derived skin resistance following Pirtle et al. (2019):

\[\begin{equation} p_{wet} = \frac{1}{h_D \times r_i + (\frac{P_r}{S_c})^\frac{2}{3}}, \tag{17} \end{equation}\]

where \(r_i\) is the skin’s resistance to water vapor transfer (s m-1), \(P_r\) is the Prandtl number (dimensionless), \(S_c\) is the Schmidt number (dimensionless), \(h_D\) is the mass transfer coefficient (m s-1). To calculate \(p_{wet}\), the mass transfer coefficient (\(h_D\)) must be known. Mass transfer refers to the movement of a substance though a fluid interface, driven by changes in the concentration gradient. The mass transfer coefficient controls the rate of diffusion and is dependent on velocity, temperature, and physical properties of the interphase. Similar to the heat transfer coefficient, the mass transfer coefficient also has two components derived from free and forced convection. We consider forced convection only (as free convention should be negligible within a measurement chamber), and this can be calculated from the heat transfer coefficient:

\[\begin{equation} h_D = (\frac{h_C}{C_p \times \rho}) \times (\frac{P_r}{S_c}) ^ \frac{2}{3}, \tag{18} \end{equation}\]

where \(P_r\) is the Prandtl number (dimensionless), \(S_c\) is the Schmidt number (dimensionless), \(h_C\) is the heat transfer coefficient (J s-1 cm-2 K-1), \(\rho\) is the density of dry air (g cm-3), and \(C_p\) is the specific heat of air (1.01 J g-1 K-1).

Simulate drought and warming

Microclimates represent the physical environments experienced by an organism. They are a necessity for mechanistic niche modelling because it is the environment experienced at the scale of the individual that needs to be provided to the equations of energy and mass balance. The microclimate model was implemented as described by Kearney et al. (2014). Specifically, it was driven by historical 0.05° grid (~5 km) daily weather input layers (air temperature, vapor pressure, wind speed, and cloud cover).

We simulated meteorological drought (defined as less than average rainfall) by modifying the micro_era5 function from NicheMapR to incorporate rainfall (rainfact) and relative humidity (rhfact) deficit factors. A default factor is 1 which is 100% of the original rainfall or relative humidity. A factor of 0.5 means 50% of the original rainfall or relative humidity. The modified function can be found on the accompanying GitHub page.

To simulate frog activity under drought and warming scenarios, we constructed four climate conditions using the micro_era5 function:

  1. current normal scenario representing the mean annual air temperature and rainfall from 1981–2010,
  2. current drought scenario representing the mean annual air temperature from 1981-2010 and annual rainfall based on 2017-2019 drought in Australia (Fig. S9),
  3. warming normal scenario representing the “business-as-usual” scenario, where the global surface temperature is estimated to increase by 4°C by 2080–2100 with no effect of drought (+4°C only), and
  4. warming drought scenario with a +4°C increasing in air temperature and annual rainfall based on 2017-2019 drought in Australia.

First, download the mcera5 microclimate data to a local directory to run the micro_era5 function faster.

# get ERA5 data with package mcera5 assign your credentials (register here:
# https://cds.climate.copernicus.eu/user/register)
uid <- "$$$$$$"
cds_api_key <- "$$$$$$$$-$$$$-$$$$-$$$$-$$$$$$$$$$$$"
ecmwfr::wf_set_key(user = uid, key = cds_api_key, service = "cds")

# bounding coordinates (in WGS84 / EPSG:4326)
c(-41.19, -20.186)
xmn <- -42
xmx <- -41
ymn <- -21
ymx <- -20

xmn <- 152
xmx <- 154
ymn <- -28
ymx <- -26

# temporal extent
st_time <- lubridate::ymd("2016:01:01")  # earliest sampling date
en_time <- lubridate::ymd("2018:12:31")  # latest sampling date

# filename and location for downloaded .nc files
file_prefix <- "era5"
op <- "YOUR DIRECTORY"

# build a request (covering multiple years)
req <- mcera5::build_era5_request(xmin = xmn, xmax = xmx, ymin = ymn, ymax = ymx,
    start_time = st_time, end_time = en_time, outfile_name = file_prefix)

mcera5::request_era5(request = req, uid = uid, out_path = op)

Next, run the micro_era5 function for the four scenarios in 2017 (representing typical rainfall year), and one for 2019 to validate the observed rainfall data.

source("/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/code/micro_era5_drought.R")

longlat <- c(153.09249, -27.6235) # Karawatha, QLD.

# Current normal 2017 scenario
micro_curr_wet <- micro_era5(loc = longlat, 
                             runshade = 1, minshade = 0, # shade parameters
                             rainfact = 1.2, rhfact = 1, # rain and RH parameters
                             warm = 0, # current climate
                             dstart = "01/01/2017", 
                             dfinish = "31/12/2017",
                             spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                             save = 0)

# Current dry 2017 scenario
micro_curr_dry <- micro_era5(loc = longlat, 
                             runshade = 1, minshade = 0, # shade parameters
                             rainfact = 0.5, rhfact = 0.1, # rain and RH parameters
                             warm = 0, # current climate
                             dstart = "01/01/2017", 
                             dfinish = "31/12/2017",
                             spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                             save = 0)

# Warming normal 2017 scenario
micro_warm_wet <- micro_era5(loc = longlat, 
                             runshade = 1, minshade = 0, # shade parameters
                             rainfact = 1.2, rhfact = 1, # rain and RH parameters
                              warm = 4, # future climate
                              dstart = "01/01/2017", 
                              dfinish = "31/12/2017",
                              spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                              save = 0)

# Warming dry 2017 scenario (simulating 2019 drought)
micro_warm_dry <- micro_era5(loc = longlat, 
                             runshade = 1, minshade = 0, # shade parameters
                             rainfact = 0.5, rhfact = 0.1, # rain and RH parameters
                             warm = 4, # future climate
                             dstart = "01/01/2017", 
                             dfinish = "31/12/2017",
                             spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                             save = 0)

# Simulate rainfall for 2019 drought
act_dry <- micro_era5(loc = longlat, 
                      runshade = 1, minshade = 0, # shade parameters
                      warm = 0, # current climate
                      dstart = "01/01/2019", 
                      dfinish = "31/12/2019",
                      spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/Spatial data/karawatha/era5', # change to your location
                      save = 0)

To verify our microclimate models, we plotted the simulated the daily rainfall for 2017 (representing typical rainfall) and 2019 (historical drought) with the observed daily rainfall in Australia for the following location: Karawatha, Southeast Queensland, Australia (153.09249, -27.6235). Karawatha provides a good case study because there are many ecotypes found in this location: ground-dwelling (e.g. Rhinella marina), arboreal (e.g. Litoria caerulea), fossorial (e.g. Cyclorana alboguttata), semi-aquatic (e.g. Litoria nasuta), and this area has experienced drought recently (2019). We extracted rainfall data from a weather station next to Karawatha which experienced “very much below average” rainfall from the Australian Bureau of Meteorology.

# Load observed rainfall for 2019
obs_rainfall <- read.csv(file.path(data_path, "obs_rainfall.csv")) %>%
    tibble::rowid_to_column("DOY") %>%
    dplyr::mutate(date = lubridate::make_date(year = 2019, month = month_num, day = day))

# Merge observed and predicted rainfall together
model_rain_wet <- as.data.frame(micro_curr_wet$RAINFALL) %>%
    tibble::rowid_to_column("DOY") %>%
    rename(rainfall_mm = "micro_curr_wet$RAINFALL") %>%
    merge(obs_rainfall, by = "DOY", all.x = TRUE)

model_2019 <- as.data.frame(act_dry$RAINFALL) %>%
    tibble::rowid_to_column("DOY") %>%
    rename(rainfall_mm = "act_dry$RAINFALL") %>%
    merge(obs_rainfall, by = "DOY", all.x = TRUE)

# 2019 drought validate
rain_dry_plot <- model_2019 %>%
    ggplot() + geom_line(aes(x = DOY, y = karawatha_19), colour = "grey") + geom_line(aes(x = DOY,
    y = rainfall_mm), colour = "red", alpha = 0.5) + labs(x = "Day of the year",
    y = expression("Daily rainfall (mm day"^{
        "-1"
    } * ")")) + ggtitle("2019 Drought") + scale_y_continuous(lim = c(0, 100), expand = c(0,
    0)) + scale_x_continuous(breaks = seq(0, 365, 50), expand = c(0, 0)) + mytheme() +
    theme(legend.position = "bottom")

# 2017 normal validate
rain_wet_plot <- model_rain_wet %>%
    ggplot() + geom_line(aes(x = DOY, y = karawatha_17), colour = "grey") + geom_line(aes(x = DOY,
    y = rainfall_mm), colour = "red", alpha = 0.5) + labs(x = "Day of the year",
    y = expression("Daily rainfall (mm day"^{
        "-1"
    } * ")")) + ggtitle("2017 Normal") + scale_y_continuous(lim = c(0, 100), expand = c(0,
    0)) + scale_x_continuous(breaks = seq(0, 365, 50), expand = c(0, 0)) + mytheme() +
    theme(legend.position = "bottom")

cowplot::plot_grid(rain_wet_plot, rain_dry_plot, ncol = 2)

Fig. S9. Simulated rainfall from the micro_era5 function (red) and the observed rainfall for Karawatha, QLD from the Australian Bureau of Meteorology (grey). The total yearly observed rainfall for 2017 was as 1100 mm, and the total simulated yearly rainfall from NicheMapR was 1097.12 mm. The total yearly observed rainfall for the 2019 drought was 598 mm, and the total simulated yearly rainfall from NicheMapR was 556.22 mm. The average yearly rainfall across 1981-2010 is around 1100 mm per year.

Simulate activity

We simulated the potential number of hours for activity in a year (\(t_{act}\)) which represents the suitable thermal and hydric conditions for the animal to move beyond their retreat to either catch prey or finding mates (Kearney and Porter, 2020). The thermoregulatory and hydroregulatory sequence in the model assumes that frogs will only be ‘active’ (i.e. moving beyond their retreat, catching prey, finding mates) between the minimum and maximum body temperature thresholds for foraging, Tmin and Tmax (°C), and the minimum tolerated hydration, min.hyd (%). In addition, if water.act = T, the frog will only be active if temperatures are within the suitable temp range, and the frog is not expected to go below allowed hydration levels (e.g. if %hydration is not below min.hyd).

To estimate the potential \(t_{act}\) for one year, we simulated the hypothetical frog to be active during the day and night (24 hours). While most frogs are nocturnal, there are some frog species found moving during the day. The water hydric parameters (e.g. skin resistance, water uptake rate, dehydration tolerance) were based on the average values of the dataset collected from the PRISMA search. The thermal parameters (minimum and maximum foraging and critical temperature) were based on Rhinalla marina which has been verified in Kearney et al. (2008).

Three water-saving strategies were constructed to broadly reflect each ecotype that use either behavioural strategies such as microhabitat selection, or physiological strategies such as increased skin resistance or skin thickness (Table S5). For example, many amphibians (espically arid specialist) seek or burrow underground to regulate body temperature and water balance without exhibiting thicker skin or higher skin resistance. This is because underground burrows are generally cooler, less varied temperature fluctuation, and more moist relative to the surface climate.

Table S5. Modified parameters for the sim.ecto function for each hypothetical frog model. The skin resistance values were based on the average empirical measurements for a typical frog and a waterproof frog in the meta-analysis. Seek shade represents microclimate simulated under shaded conditions (0-90% shade). Retreat underground represents the ability for the frog to seek suitable microclimates underground. Can climb represents the ability for the frog to seek suitable microclimates above ground level (e.g. trees, cliffs). Note, frogs are not active when underground, and water uptake only occurs during inactivity.

Water-saving strategy Skin resistance Seek shade? Retreat underground? Can climb? Ecotype
Shade only Low Yes No No Ground-dwelling
Waterproof High Yes No Yes Arboreal
Fossorial Low Yes Yes No Fossorial

It is important to note that we focus only on the direct effects of environmental change on water budgets by predicting changes in EWL rates. The conclusions we draw do not account for the indirect effects of environmental change on water budgets, such as potential changes to thermal tolerance as a result of dehydration, or the thermoregulatory difficulties that may arise as a result of habitat modification.

source("/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Drought project/code/behav_functions.R")
# Construct frog model
# compute the heat exchange by convection (extract mass transfer coefficient, Prandtl number and Schmidt number)
CONV_out <- NicheMapR::CONV_ENDO(TS     = 19, # skin temperature (°C)
                                 TENV   = 20, # fluid temperature (°C)
                                 SHAPE  = 4, # 4 is ellipsoid
                                 SURFAR = mean(resist_dat$dors_SA_cm2, na.rm = TRUE) / 10000,  # surface area for convection, m2
                                 FLTYPE = 0, # fluid type: 0 = air
                                 FURTST = 0, # test of presence of fur (length x diameter x density x depth) (-)
                                 D      = mean(resist_dat$D, na.rm = TRUE), 
                                 TFA    = 20, # initial fur/air interface temperature
                                 VEL    = mean(resist_dat$airflow_cm_s, na.rm = TRUE) / 100, # wind speed (m/s)
                                 ZFUR   = 0, # fur depth, mean (m)
                                 BP     = 101325, # barometric pressure at sea level
                                 ELEV   = 0) # elevation (m)

# basic parameters for 30 g frog
Ww_g         <- exp(mean(log(raw_dat$mean_mass_g), na.rm = TRUE)) # geometric mean wet weight of animal (g), account for uneven distribution
r_s_low      <- resist_dat %>% dplyr::filter(strategy == "none") %>% dplyr::select(r_s_est) # skin resistance
pct_wet_high <- 1 / (CONV_out[5] * mean(r_s_low$r_s_est, na.rm = TRUE) + (CONV_out[11] / CONV_out[13]) ^ 0.6666666) * 100  # % of surface area acting as a free-water exchanger (Pirtle et al 2017)

# parameters for a water-proof frog
r_s_high    <- resist_dat %>% dplyr::filter(strategy == "water-proof") %>% dplyr::select(r_s_est) # skin resistance
pct_wet_low <- 1 / (CONV_out[5] * max(r_s_high$r_s_est, na.rm = TRUE) + (CONV_out[11] / CONV_out[13]) ^ 0.6666666) * 100 # % of surface area acting as a free-water exchanger (Pirtle et al 2017)

# Thermal traits based on Rhinella marina
Tmin   <- 13.7 # minimum Tb at which activity occurs (Kearney et al 2008)
Tmax   <- 30.4 # maximum Tb at which activity occurs (Kearney et al 2008)
#T_pref <- 24 # preferred Tb (Kearney et al 2008)
CTmax  <- 37 # critical thermal minimum (affects choice of retreat) Tracy et al 2012
CTmin  <- 8 # critical thermal maximum (affects choice of retreat) Kolbe et al 2010, McCann et al 2014

# Water balance traits
min_hyd <- 80 # minimum tolerated hydration before activity declines (% of fully hydrated animals)
hyd.death <- 50 # minimum tolerated hydration before death (% of fully hydrated animals)
wu_rate <- wu_dat %>% dplyr::filter(strategy == "none") %>% dplyr::select(mg_h_mean)
hyd_rate <- exp(mean(log(wu_rate$mg_h_mean), na.rm = TRUE)) / 1000 # geometric mean rehydration rate (g/h), account for uneven distribution
# depends on current and max hydration like this: hyd.rate * ((hyd - hyd.current) / hyd)

# behav = 'diurnal', 'nocturnal' or 'both'
# water; does the frog select depth according to water potential? (TRUE or FALSE)
# water.act; does the activity depend on water loss? (TRUE or FALSE)

# SHADE MODEL
shad_curr_wet_mod <- sim.ecto(micro_curr_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = FALSE, water.act = TRUE)

shad_curr_dry_mod <- sim.ecto(micro_curr_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = FALSE, water.act = TRUE)

shad_warm_wet_mod <- sim.ecto(micro_warm_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = FALSE, water.act = TRUE)

shad_warm_dry_mod <- sim.ecto(micro_warm_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = FALSE, water.act = TRUE)

# WATER-PROOF MODEL
tree_curr_wet_mod <- sim.ecto(micro_curr_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = TRUE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_low, 
                              water = TRUE, water.act = TRUE)

tree_curr_dry_mod <- sim.ecto(micro_curr_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = TRUE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_low, 
                              water = TRUE, water.act = TRUE)

tree_warm_wet_mod <- sim.ecto(micro_warm_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = TRUE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_low, 
                              water = TRUE, water.act = TRUE)

tree_warm_dry_mod <- sim.ecto(micro_warm_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = FALSE, climb = TRUE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_low, 
                              water = TRUE, water.act = TRUE)

# BURROWING MODEL
burr_curr_wet_mod <- sim.ecto(micro_curr_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = TRUE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = TRUE, water.act = TRUE)

burr_curr_dry_mod <- sim.ecto(micro_curr_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = TRUE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = TRUE, water.act = TRUE)

burr_warm_wet_mod <- sim.ecto(micro_warm_wet, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = TRUE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = TRUE, water.act = TRUE)

burr_warm_dry_mod <- sim.ecto(micro_warm_dry, Ww_g = Ww_g, shape = 4, 
                              Tmax = Tmax, Tmin = Tmin, CTmin = CTmin, CTmax = CTmax,
                              behav = 'both', in.shade = TRUE, burrow = TRUE, climb = FALSE,
                              min.hyd = min_hyd, hyd.death = hyd.death,
                              hyd.rate = hyd_rate, pct_wet = pct_wet_high, 
                              water = TRUE, water.act = TRUE)
# SHADE MODEL
shad_curr_wet_df <- data.frame(shad_curr_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = shad_curr_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_wet = length(active[active == TRUE]))

shad_curr_dry_df <- data.frame(shad_curr_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = shad_curr_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_dry = length(active[active == TRUE]))

shad_warm_wet_df <- data.frame(shad_warm_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = shad_warm_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_wet = length(active[active == TRUE]))

shad_warm_dry_df <- data.frame(shad_warm_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = shad_warm_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_dry = length(active[active == TRUE]))

shad_model <- shad_curr_wet_df %>%
    merge(shad_curr_dry_df, by = "day") %>%
    merge(shad_warm_wet_df, by = "day") %>%
    merge(shad_warm_dry_df, by = "day") %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry", "warm_wet",
        "curr_dry", "curr_wet")), season = case_when(day >= 335 ~ "summer", day >=
        1 & day <= 61 ~ "summer", day >= 62 & day <= 153 ~ "autumn", day >= 154 &
        day <= 244 ~ "winter", day >= 245 & day <= 334 ~ "spring"))

# TREE MODEL
tree_curr_wet_df <- data.frame(tree_curr_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = tree_curr_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_wet = length(active[active == TRUE]))

tree_curr_dry_df <- data.frame(tree_curr_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = tree_curr_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_dry = length(active[active == TRUE]))

tree_warm_wet_df <- data.frame(tree_warm_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = tree_warm_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_wet = length(active[active == TRUE]))

tree_warm_dry_df <- data.frame(tree_warm_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = tree_warm_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_dry = length(active[active == TRUE]))

tree_model <- tree_curr_wet_df %>%
    merge(tree_curr_dry_df, by = "day") %>%
    merge(tree_warm_wet_df, by = "day") %>%
    merge(tree_warm_dry_df, by = "day") %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry", "warm_wet",
        "curr_dry", "curr_wet")), season = case_when(day >= 335 ~ "summer", day >=
        1 & day <= 61 ~ "summer", day >= 62 & day <= 153 ~ "autumn", day >= 154 &
        day <= 244 ~ "winter", day >= 245 & day <= 334 ~ "spring"))

# FOSSORIAL MODEL
burr_curr_wet_df <- data.frame(burr_curr_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = burr_curr_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_wet = length(active[active == TRUE]))

burr_curr_dry_df <- data.frame(burr_curr_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = burr_curr_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(curr_dry = length(active[active == TRUE]))

burr_warm_wet_df <- data.frame(burr_warm_wet_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = burr_warm_wet_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_wet = length(active[active == TRUE]))

burr_warm_dry_df <- data.frame(burr_warm_dry_mod$act) %>%
    tibble::rowid_to_column("hour") %>%
    dplyr::rename(active = burr_warm_dry_mod.act) %>%
    dplyr::mutate(day = ceiling(1:8760/24)) %>%
    dplyr::group_by(day) %>%
    dplyr::summarise(warm_dry = length(active[active == TRUE]))

burr_model <- burr_curr_wet_df %>%
    merge(burr_curr_dry_df, by = "day") %>%
    merge(burr_warm_wet_df, by = "day") %>%
    merge(burr_warm_dry_df, by = "day") %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry", "warm_wet",
        "curr_dry", "curr_wet")), season = case_when(day >= 335 ~ "summer", day >=
        1 & day <= 61 ~ "summer", day >= 62 & day <= 153 ~ "autumn", day >= 154 &
        day <= 244 ~ "winter", day >= 245 & day <= 334 ~ "spring"))

Model output

Table S6a - Summary

Table S6a. Total potential activity hours per year (\(t_{act}\)) for a 8.81 g frog under different warming (current or warming) and drought (normal or drought) conditions with different water-saving strategies.

data.frame(strategy = c("Shade only", "Shade only", "Shade only", "Shade only", "Waterproof",
    "Waterproof", "Waterproof", "Waterproof", "Burrowing", "Burrowing", "Burrowing",
    "Burrowing"), temp = c("current", "current", "warming", "warming"), rain = c("normal",
    "drought"), t_act_h = c(sum(shad_curr_wet_df$curr_wet), sum(shad_curr_dry_df$curr_dry),
    sum(shad_warm_wet_df$warm_wet), sum(shad_warm_dry_df$warm_dry), sum(tree_curr_wet_df$curr_wet),
    sum(tree_curr_dry_df$curr_dry), sum(tree_warm_wet_df$warm_wet), sum(tree_warm_dry_df$warm_dry),
    sum(burr_curr_wet_df$curr_wet), sum(burr_curr_dry_df$curr_dry), sum(burr_warm_wet_df$warm_wet),
    sum(burr_warm_dry_df$warm_dry)), t_act_per = c(sum(shad_curr_wet_df$curr_wet)/8760 *
    100, sum(shad_curr_dry_df$curr_dry)/8760 * 100, sum(shad_warm_wet_df$warm_wet)/8760 *
    100, sum(shad_warm_dry_df$warm_dry)/8760 * 100, sum(tree_curr_wet_df$curr_wet)/8760 *
    100, sum(tree_curr_dry_df$curr_dry)/8760 * 100, sum(tree_warm_wet_df$warm_wet)/8760 *
    100, sum(tree_warm_dry_df$warm_dry)/8760 * 100, sum(burr_curr_wet_df$curr_wet)/8760 *
    100, sum(burr_curr_dry_df$curr_dry)/8760 * 100, sum(burr_warm_wet_df$warm_wet)/8760 *
    100, sum(burr_warm_dry_df$warm_dry)/8760 * 100)) %>%
    knitr::kable(col.names = c("Water-saving strategy", "Warming simulation", "Drought simulation",
        "$t_{act}$ (h)", "$t_{act}$ (%)"))
Water-saving strategy Warming simulation Drought simulation \(t_{act}\) (h) \(t_{act}\) (%)
Shade only current normal 3971 45
Shade only current drought 3792 43
Shade only warming normal 4322 49
Shade only warming drought 4103 47
Waterproof current normal 4767 54
Waterproof current drought 4553 52
Waterproof warming normal 4939 56
Waterproof warming drought 4691 54
Burrowing current normal 4286 49
Burrowing current drought 4190 48
Burrowing warming normal 4715 54
Burrowing warming drought 4599 52

Table S6b - Relative change year

Table S6b. Change in \(t_{act}\) (%) for each water-saving strategy relative to the current normal scenario under warming only, drought only, and warming and drought combined.

data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(sum(shad_curr_wet_df$curr_wet),
    sum(tree_curr_wet_df$curr_wet), sum(burr_curr_wet_df$curr_wet)), curr_dry = c(sum(shad_curr_dry_df$curr_dry),
    sum(tree_curr_dry_df$curr_dry), sum(burr_curr_dry_df$curr_dry)), warm_wet = c(sum(shad_warm_wet_df$warm_wet),
    sum(tree_warm_wet_df$warm_wet), sum(burr_warm_wet_df$warm_wet)), warm_dry = c(sum(shad_warm_dry_df$warm_dry),
    sum(tree_warm_dry_df$warm_dry), sum(burr_warm_dry_df$warm_dry))) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    knitr::kable(col.names = c("Water-saving strategy", "$\\Delta$ warming only (%)",
        "$\\Delta$ drought only (%)", "$\\Delta$ warming and drought (%)"))
Water-saving strategy \(\Delta\) warming only (%) \(\Delta\) drought only (%) \(\Delta\) warming and drought (%)
Shade only 8.8 -4.5 3.3
Waterproof 3.6 -4.5 -1.6
Burrowing 10.0 -2.2 7.3

Table S6c - Relative change season

Table S6c. Change in \(t_{act}\) (%) for each water-saving strategy relative to the current normal scenario under warming only, drought only, and warming and drought combined.

# summer
shad_model_summer <- shad_model %>%
    dplyr::filter(season == "summer") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tree_model_summer <- tree_model %>%
    dplyr::filter(season == "summer") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

burr_model_summer <- burr_model %>%
    dplyr::filter(season == "summer") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tab_summer <- data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(shad_model_summer$hours[4],
    tree_model_summer$hours[4], burr_model_summer$hours[4]), curr_dry = c(shad_model_summer$hours[3],
    tree_model_summer$hours[3], burr_model_summer$hours[3]), warm_wet = c(shad_model_summer$hours[2],
    tree_model_summer$hours[2], burr_model_summer$hours[2]), warm_dry = c(shad_model_summer$hours[1],
    tree_model_summer$hours[1], burr_model_summer$hours[1])) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    tibble::add_row(strategy = "**Summer**", .before = 1)

# autumn
shad_model_autumn <- shad_model %>%
    dplyr::filter(season == "autumn") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tree_model_autumn <- tree_model %>%
    dplyr::filter(season == "autumn") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

burr_model_autumn <- burr_model %>%
    dplyr::filter(season == "autumn") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tab_autumn <- data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(shad_model_autumn$hours[4],
    tree_model_autumn$hours[4], burr_model_autumn$hours[4]), curr_dry = c(shad_model_autumn$hours[3],
    tree_model_autumn$hours[3], burr_model_autumn$hours[3]), warm_wet = c(shad_model_autumn$hours[2],
    tree_model_autumn$hours[2], burr_model_autumn$hours[2]), warm_dry = c(shad_model_autumn$hours[1],
    tree_model_autumn$hours[1], burr_model_autumn$hours[1])) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    tibble::add_row(strategy = "**Autumn**", .before = 1)

# winter
shad_model_winter <- shad_model %>%
    dplyr::filter(season == "winter") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tree_model_winter <- tree_model %>%
    dplyr::filter(season == "winter") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

burr_model_winter <- burr_model %>%
    dplyr::filter(season == "winter") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tab_winter <- data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(shad_model_winter$hours[4],
    tree_model_winter$hours[4], burr_model_winter$hours[4]), curr_dry = c(shad_model_winter$hours[3],
    tree_model_winter$hours[3], burr_model_winter$hours[3]), warm_wet = c(shad_model_winter$hours[2],
    tree_model_winter$hours[2], burr_model_winter$hours[2]), warm_dry = c(shad_model_winter$hours[1],
    tree_model_winter$hours[1], burr_model_winter$hours[1])) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    tibble::add_row(strategy = "**Winter**", .before = 1)

# spring
shad_model_spring <- shad_model %>%
    dplyr::filter(season == "spring") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tree_model_spring <- tree_model %>%
    dplyr::filter(season == "spring") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

burr_model_spring <- burr_model %>%
    dplyr::filter(season == "spring") %>%
    dplyr::group_by(condition) %>%
    dplyr::summarise(hours = sum(hours))

tab_spring <- data.frame(strategy = c("Shade only", "Waterproof", "Burrowing"), curr_wet = c(shad_model_spring$hours[4],
    tree_model_spring$hours[4], burr_model_spring$hours[4]), curr_dry = c(shad_model_spring$hours[3],
    tree_model_spring$hours[3], burr_model_spring$hours[3]), warm_wet = c(shad_model_spring$hours[2],
    tree_model_spring$hours[2], burr_model_spring$hours[2]), warm_dry = c(shad_model_spring$hours[1],
    tree_model_spring$hours[1], burr_model_spring$hours[1])) %>%
    dplyr::mutate(delta_warm = (warm_wet - curr_wet)/curr_wet * 100, delta_dry = (curr_dry -
        curr_wet)/curr_wet * 100, delta_warm_dry = (warm_dry - curr_wet)/curr_wet *
        100) %>%
    dplyr::select(-c(curr_wet:warm_dry)) %>%
    tibble::add_row(strategy = "**Spring**", .before = 1)

# Render table
bind_rows(tab_summer, tab_autumn, tab_winter, tab_spring) %>%
    remove_rownames() %>%
    knitr::kable(col.names = c("Water-saving strategy", "$\\Delta$ warming only (%)",
        "$\\Delta$ drought only (%)", "$\\Delta$ warming and drought (%)"))
Water-saving strategy \(\Delta\) warming only (%) \(\Delta\) drought only (%) \(\Delta\) warming and drought (%)
Summer
Shade only -8.3 -11.6 -17.73
Waterproof -8.8 -10.8 -19.02
Burrowing -4.6 -4.5 -9.97
Autumn
Shade only 5.0 -1.6 3.40
Waterproof 1.5 -2.0 0.12
Burrowing 6.0 -1.1 5.19
Winter
Shade only 74.6 -1.9 67.16
Waterproof 38.0 -1.6 33.05
Burrowing 70.4 -2.2 67.00
Spring
Shade only 1.8 -2.4 -4.24
Waterproof -1.4 -3.3 -6.98
Burrowing 4.0 -1.3 1.94

Figures

Code to produce the main document figures are detailed below. Figures produced were further modified in Adobe Illustrator for publication.

Figure 1 - AI risk

Create plots for main text figure 1.

# Reproject maps
rob_proj <- "+proj=robin +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"
world_rob <- spTransform(world_spdf, CRSobj = rob_proj)

# land
data("land", package = "tmap")
land_raster <- as(land, "Raster")  # convert from star to raster
land_df <- raster::as.data.frame(raster::rasterToPoints(land_raster))

elevation_raster <- projectRaster(land_raster$elevation, crs = rob_proj)
slope_raster <- raster::terrain(elevation_raster, opt = "slope")
aspect_raster <- raster::terrain(elevation_raster, opt = "aspect")
hill_raster <- hillShade(slope_raster, aspect_raster, 40, 270)  #setting the elevation angle (of the sun) to 40 and the direction angle of the light to 270
hill_m <- rasterToPoints(hill_raster)
hill_df <- data.frame(hill_m)
colnames(hill_df) <- c("lon", "lat", "hill")

# Fig 1a - AI current
AI_rob <- raster::projectRaster(ai_rast, crs = rob_proj)
AI_df_rob <- raster::as.data.frame(raster::rasterToPoints(AI_rob))
AI_df_rob <- AI_df_rob %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

AI_2C_rob <- projectRaster(ai_2C_rast, crs = rob_proj)
AI_2C_df_rob <- raster::as.data.frame(raster::rasterToPoints(AI_2C_rob))
AI_2C_df_rob <- AI_2C_df_rob %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

AI_4C_rob <- projectRaster(ai_4C_rast, crs = rob_proj)
AI_4C_df_rob <- raster::as.data.frame(raster::rasterToPoints(AI_4C_rob))
AI_4C_df_rob <- AI_4C_df_rob %>%
    # Recode
dplyr::mutate(category = case_when(is.infinite(layer) ~ "Humid", layer >= 0.65 ~
    "Humid", layer >= 0.5 & layer < 0.65 ~ "Dry sub-humid", layer >= 0.2 & layer <
    0.5 ~ "Semi-arid", layer >= 0.05 & layer < 0.2 ~ "Arid", layer < 0.05 ~ "Hyper-arid")) %>%
    # Convert to ordered factor
dplyr::mutate(category = factor(category, levels = c("Hyper-arid", "Arid", "Semi-arid",
    "Dry sub-humid", "Humid"), ordered = TRUE))

arid_col <- c("#8E063B", "#CB6D53", "#E99A2C", "#F5D579", "white")
aridity_plot <- ggplot() + geom_raster(data = AI_df_rob, aes(y = y, x = x, fill = category)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = arid_col, guide = guide_legend(reverse = TRUE)) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Aridity Index (1981-2010)") +
    scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07,
    1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)

# Fig 1b - Species richness
anuran_rob <- projectRaster(anuran_sr, crs = rob_proj)
anuran_df_rob <- raster::as.data.frame(raster::rasterToPoints(anuran_rob)) %>%
    dplyr::rename(species_n = layer)

sp_breaks = c(1, 5, 25, 100)
anuran_plot <- ggplot() + geom_raster(data = anuran_df_rob, aes(y = y, x = x, fill = species_n)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + colorspace::scale_fill_continuous_sequential(palette = "BluGrn",
    trans = "log", breaks = sp_breaks, labels = sp_breaks) + ggnewscale::new_scale("fill") +
    geom_raster(data = hill_df %>%
        filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle("Anuran species richness") +
    scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07,
    1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed()

AI_merged <- merge(AI_df_rob, AI_2C_df_rob, by = c("x", "y"), all.x = T) %>%
    merge(AI_4C_df_rob, by = c("x", "y"), all.x = T) %>%
    dplyr::rename(layer_current = layer.x, category_current = category.x, layer_2C = layer.y,
        category_2C = category.y, layer_4C = layer, category_4C = category) %>%
    dplyr::mutate(change_2C = (layer_2C - layer_current/layer_current) * 100, change_2C_AI = case_when(change_2C >=
        -2 & change_2C < 2 ~ "No change to wetter", change_2C >= -10 & change_2C <
        -2 ~ ">-2 to -10%", change_2C >= -20 & change_2C < -10 ~ ">-10 to -20%",
        change_2C >= -40 & change_2C < -20 ~ ">-20 to -40%", change_2C >= -80 & change_2C <
            -40 ~ ">-40 to -80%", change_2C < -80 ~ "<-80%"), change_4C = (layer_4C -
        layer_current/layer_current) * 100, change_4C_AI = case_when(change_4C >=
        -2 & change_4C < 2 ~ "No change to wetter", change_4C >= -10 & change_4C <
        -2 ~ ">-2 to -10%", change_4C >= -20 & change_4C < -10 ~ ">-10 to -20%",
        change_4C >= -40 & change_4C < -20 ~ ">-20 to -40%", change_4C >= -80 & change_4C <
            -40 ~ ">-40 to -80%", change_4C < -80 ~ "<-80%")) %>%
    filter(category_current != "Hyper-arid") %>%
    dplyr::mutate(change_2C_AI = factor(change_2C_AI, levels = c("<-80%", ">-40 to -80%",
        ">-20 to -40%", ">-10 to -20%", ">-2 to -10%", "No change to wetter"), ordered = TRUE),
        change_4C_AI = factor(change_4C_AI, levels = c("<-80%", ">-40 to -80%", ">-20 to -40%",
            ">-10 to -20%", ">-2 to -10%", "No change to wetter"), ordered = TRUE))

change_col <- c("#B13F63", "#D35D60", "#E38566", "#EEAC7D", "#F5D1A8", "white")

# Fig 1C - 2C Difference
change_2C_plot <- ggplot() + geom_raster(data = AI_merged, aes(y = y, x = x, fill = change_2C_AI)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = change_col, na.value = "white") +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in dryness (" *
    Delta * "AI +2°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

# Fig 1d - 4C Difference
change_4C_plot <- ggplot() + geom_raster(data = AI_merged, aes(y = y, x = x, fill = change_4C_AI)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = change_col, na.value = "white") +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in dryness (" *
    Delta * "AI +4°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)

# Fig 1e - Dryness and species richness
arid_col_2 <- c("#8E063B", "#CB6D53", "#E99A2C", "#F5D579", "light grey")
species_ai_plot <- ai_sp_df %>%
    ggplot(aes(x = aridity, y = species_n, colour = category)) + geom_point(size = 2) +
    coord_trans(x = "sqrt") + scale_colour_manual(values = arid_col_2, guide = guide_legend(reverse = TRUE)) +
    scale_x_continuous(limits = c(0, 3), breaks = c(0, 0.05, 0.2, 0.5, 0.65)) + xlab("Precipitation / Evapotranspiration") +
    ylab("Species richness") + mytheme() + theme(legend.position = "none", axis.text.x = element_blank(),
    axis.ticks.x = element_blank())

# Fig 1f - Dryness and species richness by ecotype
ecotype_ai_plot <- ai_sp_df %>%
    dplyr::filter(aridity <= 3) %>%
    dplyr::select(aridity, species_n:stream_n) %>%
    tidyr::pivot_longer(!aridity, names_to = "ecotype", values_to = "mean") %>%
    dplyr::filter(ecotype != "species_n") %>%
    drop_na(mean) %>%
    dplyr::mutate(ecotype = factor(ecotype, levels = c("fossorial_n", "ground_n",
        "aquatic_n", "arboreal_n", "semi_aq_n", "stream_n"))) %>%
    ggplot(aes(x = aridity, y = ecotype, group = ecotype, fill = ecotype)) + ggridges::stat_density_ridges(scale = 1,
    rel_min_height = 0.01, alpha = 0.5, show.legend = FALSE) + scale_fill_viridis_d() +
    scale_x_continuous(trans = "sqrt") + labs(x = NULL, y = NULL) + mytheme()

# Fig 1g - Change in species AI Merge summary data by row
arid_sp_comb <- data.frame(bind_rows(ai_sp_sum, ai_2C_sp_sum, ai_4C_sp_sum))
arid_sp_comb$scenario <- forcats::fct_relevel(arid_sp_comb$scenario, "Current")

species_occ_plot <- arid_sp_comb %>%
    ggplot(aes(x = category, y = log(all_freq), group = scenario, colour = scenario,
        shape = scenario)) + geom_point(position = position_dodge(width = 0.5), size = 1.5) +
    scale_colour_manual(values = c("#F5D579", "#CB6D53", "#8E063B")) + scale_y_continuous(breaks = pretty(log(arid_sp_comb$all_freq)),
    labels = pretty(arid_sp_comb$all_freq)) + ylab("% species") + xlab(NULL) + mytheme() +
    theme(legend.position = "none")

# Fig 1
plot_grid(species_ai_plot, ecotype_ai_plot, species_occ_plot, align = "v", ncol = 3)  # plot in between.
cowplot::plot_grid(aridity_plot + theme(legend.position = "bottom"), anuran_plot +
    theme(legend.position = "bottom"), change_2C_plot + theme(legend.position = "bottom"),
    change_4C_plot + theme(legend.position = "bottom"), align = "h", axis = "bt",
    ncol = 2)

Figure 2 - PDSI risk

Create plots for main text figure 2.

PDSI_risk_rob <- raster::projectRaster(raster::stack(PDSI_2C_diff_rast, PDSI_4C_diff_rast, PDSI_freq_diff, PDSI_dur_diff,
                                                     resample(anuran_sr, PDSI_4C_diff_rast)), 
                                       crs = rob_proj)
                             
PDSI_risk_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_risk_rob)) %>%
  dplyr::rename("sp_n" = layer) %>%
  dplyr::filter(!is.na(sp_n)) %>%
  dplyr::mutate(delta_int_2C_bin = ifelse(delta_int_2C < -1, 1, 0), # delta_PDSI < -1
         delta_int_4C_bin = ifelse(delta_int_4C < -1, 1, 0), # delta_PDSI < -1
         delta_freq_2C_bin = ifelse(delta_freq_2C >1, 1, 0), # month > 1
         delta_freq_4C_bin = ifelse(delta_freq_4C >1, 1, 0), # month > 1
         delta_dur_2C_bin = ifelse(delta_dur_2C >1, 1, 0), # month > 1
         delta_dur_4C_bin = ifelse(delta_dur_4C >1, 1, 0)) %>% # month > 1 
  dplyr::rowwise() %>%
  dplyr::mutate(count_2C = sum(delta_int_2C_bin, delta_freq_2C_bin, delta_dur_2C_bin, na.rm = T),
         
         count_4C = sum(delta_int_4C_bin, delta_freq_4C_bin, delta_dur_4C_bin, na.rm = T),
         risk_2C  = sp_n * count_2C,
         risk_4C  = sp_n * count_4C,
         count_2C = factor(count_2C, levels = c("3", "2", "1")),
         count_4C = factor(count_4C, levels = c("3", "2", "1"))
         ) %>%
  data.frame()

# Plot
PDSI_risk_2C_plot <- ggplot() +
  geom_raster(data = PDSI_risk_df, aes(y = y, x = x, fill = count_2C)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_discrete_sequential(palette = "RedOr", rev = F) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  ggtitle(expression("+2°C by 2080-2100")) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) +
  coord_fixed(ratio = 1) # fixed ratio

PDSI_risk_4C_plot <- ggplot() +
  geom_raster(data = PDSI_risk_df, aes(y = y, x = x, fill = count_4C)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_discrete_sequential(palette = "RedOr", rev = F) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  ggtitle(expression("+4°C by 2080-2100")) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) +
  coord_fixed(ratio = 1) # fixed ratio

sp_2C_plot <- PDSI_risk_df %>%
  dplyr::mutate(risk_2C_cat = case_when(
    risk_2C == 0 ~ '0',
    risk_2C > 0 & risk_2C <=1 ~ '<1',
    risk_2C > 1 & risk_2C < 5 ~ '>1 to 5',
    risk_2C >= 5 & risk_2C < 10 ~ '>5 to 10',
    risk_2C >= 10 & risk_2C < 20 ~ '>10 to 20',
    risk_2C >= 20 & risk_2C < 100 ~ '>20 to 100',
    risk_2C >= 100 & risk_2C < 200 ~ '>100 to 200',
    risk_2C > 200 ~ '>200'),
    risk_2C = na_if(risk_2C, 0),
    risk_2C_cat = factor(risk_2C_cat,
                                   levels = c('>200','>100 to 200', '>20 to 100','>10 to 20', '>5 to 10', '>1 to 5', '<1'))) %>%
  ggplot() +
  geom_raster(aes(y = y, x = x, fill = risk_2C_cat)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_discrete_sequential(palette = "Heat", rev = F) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) +
  coord_fixed(ratio = 1) # fixed ratio

sp_4C_plot <- PDSI_risk_df %>%
  dplyr::mutate(risk_4C_cat = case_when(
    risk_4C == 0 ~ '0',
    risk_4C > 0 & risk_4C <=1 ~ '<1',
    risk_4C > 1 & risk_4C < 5 ~ '>1 to 5',
    risk_4C >= 5 & risk_4C < 10 ~ '>5 to 10',
    risk_4C >= 10 & risk_4C < 20 ~ '>10 to 20',
    risk_4C >= 20 & risk_4C < 100 ~ '>20 to 100',
    risk_4C >= 100 & risk_4C < 200 ~ '>100 to 200',
    risk_4C > 200 ~ '>200'),
    risk_4C = na_if(risk_4C, 0),
    risk_4C_cat = factor(risk_4C_cat,
                                   levels = c('>200','>100 to 200', '>20 to 100','>10 to 20', '>5 to 10', '>1 to 5', '<1'))) %>%
  ggplot() +
  geom_raster(aes(y = y, x = x, fill = risk_4C_cat)) +
  geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
  scale_fill_discrete_sequential(palette = "Heat", rev = F) +
  ggnewscale::new_scale("fill") +
  geom_raster(data = hill_df %>% filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
  scale_fill_gradient(low = "black", high = "grey") +
  scale_alpha_continuous(trans = "reverse") +
  theme_void() + ylab(NULL) + xlab(NULL) +
  scale_y_continuous(limits = c(-61e5, 85e5), expand = c(0, 0)) +
  scale_x_continuous(limits = c(-15e6, 16e6), expand = c(0, 0)) +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        plot.title = element_text(size = 10)) +
  coord_fixed(ratio = 1) # fixed ratio

cowplot::plot_grid(PDSI_risk_2C_plot + theme(legend.position = "none"),
                   PDSI_risk_4C_plot + theme(legend.position = "none"),
                   sp_2C_plot + theme(legend.position = "none"),
                   sp_4C_plot + theme(legend.position = "none"),
                   ncol = 2,
                   align = "h", axis = "bt", labels = c('a', 'b', 'c', 'd'))
#PDSI_risk_df %>%
  #group_by(count_2C) %>%
  #summarise(length = length(count_2C)) %>%
  #mutate(freq = length / length(PDSI_risk_df$count_2C) * 100)

#PDSI_risk_df %>%
  #group_by(count_4C) %>%
  #summarise(length = length(count_4C)) %>%
  #mutate(freq = length / length(PDSI_risk_df$count_4C) * 100)

Figure 3 - Water loss risk

Run the ectotherm function from NicheMapR for all 12 months from the Terra Climate raster files containing the mean wind speed (m s-1), maximum air temperature (°C), and vapour pressure deficit (VPD; kPa) for the current (1981 to 2010), +2°C and +4°C scenario. From the ecotherm model, we extracted the EWL (g h-1) for each raster pixel to determine the spatial variation in EWL.

## Current ## ---------------------------------------
elev      <- getData("worldclim", var = "alt", res = 2.5)
ws_full   <-  raster::brick(file.path(spatial_path, 'TerraClimate19812010_ws.nc')) # 10m, m/s
tmax_full <- raster::brick(file.path(spatial_path, 'TerraClimate19812010_tmax.nc')) # 2m, deg C
vpd_full  <- raster::brick(file.path(spatial_path, 'TerraClimate19812010_vpd.nc')) # 2m, kpa
Tbs       <- crop(tmax_full, extent(elev))
EWLs      <- Tbs 

# Run ectotherm model for each month and save on local drive (current scenario)
for(month in 1:12){
  # Temperature
  Ta.w   <- crop(tmax_full[[month]], extent(elev))
  esat   <- VAPPRS(Ta.w)
  # RH
  e      <- esat - crop(vpd_full[[month]], extent(elev)) * 1000
  RH.w   <- e / esat * 100
  RH.w[RH.w < 0] <- 0
  # Wind speed
  Wind.w <- crop(ws_full[[month]], extent(elev))
  Vstar  <- 0.4 * Wind.w / log((100 / 0.15) + 1) # friction velocity
  Wind.w <- 2.5 * Vstar * log((1 / 0.15) + 1) # correct for reference height (10 m) to ground level (1 cm) assuming level ground
  # compute atmospheric pressure (kPa)
  P.w <- 101325 * ((1 - (0.0065 * elev / 288)) ^ (1 / 0.190284)) / 1000
  
  # Get raster values
  Ta  <- getValues(Ta.w)
  RH  <- getValues(RH.w)
  P   <- getValues(P.w)
  Pa  <- getValues(e)
  ws  <- getValues(Wind.w)
  P[!is.na(Ta) & is.na(P)] <- 101.325
  Ta2 <- Ta[!is.na(Ta)]
  RH2 <- RH[!is.na(Ta)]
  P2  <- P[!is.na(Ta)]
  ws2 <- ws[!is.na(Ta)]
  Pa2 <- Pa[!is.na(Ta)]
  
  div <- 10
  Twb <- Ta2[1:floor(length(Ta2) / div)]
  micro_base <- micro_global()
  
  for(k in 1:div){
    micro <- micro_base
    if(k == 1){
      extra <- round(24 - (length(Twb) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb, rep(Ta2[1], extra))
      start <- 1
      end   <- length(Twb)
    }
    if(k > 1 & k < div){
      fact  <- (length(Twb) * (k - 1) + k - 1)
      Twb4  <- Ta2[fact:(fact + length(Twb))]
      extra <- round(24 - (length(Twb4) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb4, rep(Ta2[1], extra))
      start <- fact
      end   <- fact + length(Twb)
    }        
    if(k == div){
      fact  <- (length(Twb) * (k - 1) + k - 1)
      Twb4  <- Ta2[fact:length(Ta2)]
      extra <- round(24 - (length(Twb4) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb4, rep(Ta2[1], extra))
      start <- fact
      end   <- length(Ta2)
    } 
    
    soilnames     <- dimnames(micro$soil)
    metoutnames   <- dimnames(micro$metout)
    tcondnames    <- dimnames(micro$tcond)
    specheatnames <- dimnames(micro$specheat)
    densitnames   <- dimnames(micro$densit)
    plantnames    <- dimnames(micro$plant)
    
    micro$metout   <- t(array(micro$metout[1,], dim = c(ncol(micro$metout), length(Twb4))))
    dimnames(micro$metout) <- metoutnames
    micro$soil     <- t(array(micro$soil[1,], dim = c(ncol(micro$soil), length(Twb4))))
    dimnames(micro$soil) <- soilnames
    micro$tcond    <- t(array(micro$tcond[1,], dim = c(ncol(micro$tcond), length(Twb4))))
    dimnames(micro$tcond) <- tcondnames
    micro$specheat <- t(array(micro$specheat[1,], dim = c(ncol(micro$specheat), length(Twb4))))
    dimnames(micro$specheat) <- specheatnames  
    micro$densit   <- t(array(micro$densit[1,], dim = c(ncol(micro$densit), length(Twb4))))
    dimnames(micro$densit) <- densitnames      
    micro$plant    <- t(array(micro$plant[1,], dim = c(ncol(micro$plant), length(Twb4))))
    dimnames(micro$plant) <- plantnames 
    
    micro$shadmet <- micro$metout
    micro$shadsoil <- micro$soil
    micro$humid <- micro$soil
    micro$shadhumid <- micro$soil
    micro$soilpot <- micro$soil
    micro$shadpot <- micro$soil
    micro$soilmoist <- micro$soil
    micro$shadmoist <- micro$soil
    micro$shadtcond <- micro$tcond
    micro$shaddensit <- micro$densit
    micro$shadspecheat <- micro$specheat
    micro$shadplant <- micro$plant
    micro$RAINFALL <- rep(0, length(Twb4)/24)
    micro$minshade <- rep(0, length(Twb4)/24)
    micro$maxshade <- rep(90, length(Twb4)/24)
    micro$nyears <- ceiling(length(Twb4)/24/365)
    
    # replace first line of microclimate input with air temperature and humidity at which to compute Tw
    micro$metout[1:length(Twb4),c(3,4,14)] <- c(Ta2[start:end], rep(Ta2[1], extra)) # set air and sky temperature
    micro$metout[1:length(Twb4),c(5,6)] <- c(RH2[start:end], rep(RH2[1], extra)) # set relative humidity
    # micro$metout[1:length(Twb3),c(7,8)] <- 0.05 # set wind speed to low (sensitive to this)
    micro$soil[1:length(Twb4),3] <- c(Ta2[start:end], rep(Ta2[1], extra)) # set surface soil temperature to air temperature
    micro$metout[1:length(Twb4), 2] <- rep(seq(0, 23 * 60, 60), length(Ta2)/24 + 1)[1:length(Twb4)]
    #micro$metout[1:length(Twb3), 1] <- seq(0, 23 * 60, 60)[1:length(Twb3)]
    preshr <- c(P2[start:end], rep(P2[1], extra))*1000          
    
    micro$metout[1:length(Twb4),c(7,8)] <- c(ws2[start:end], rep(ws2[1], extra)) # set wind speed    
    
    # run the ectotherm model 
    message(paste('running ectotherm simulation for month ',month,' for ', length(Twb4),' sites \n'))
    ptm <- proc.time() # Start timing
    gc()
    ecto <- ectotherm(Ww_g = 8.7,
                      live = 0,
                      pct_wet = 87,
                      shape = 4, # frog
                      preshr = preshr)
    message(paste0('runtime ', (proc.time() - ptm)[3], ' seconds')) # Stop the clock
    gc()
    environ <- as.data.frame(ecto$environ)
    masbal  <- as.data.frame(ecto$masbal)
    if(k == 1){
      Tb.ectotherm  <- environ$TC[1:(nrow(environ) - extra)]
      EWL.ectotherm <- masbal$H2OCut_g[1:(nrow(masbal) - extra)]
    }else{
      Tb.ectotherm  <- c(Tb.ectotherm, environ$TC[1:(nrow(environ) - extra)])
      EWL.ectotherm <- c(EWL.ectotherm, masbal$H2OCut_g[1:(nrow(masbal) - extra)])
    }
  }
  Tb2     <- Ta
  Tb2[!is.na(Ta)] <- Tb.ectotherm
  Tb.grid <- Ta.w
  Tb.grid <- setValues(Tb.grid, Tb2)
  #plot(Tb.grid)
  #map('world', add = TRUE)
  
  EWL2 <- Ta
  EWL2[!is.na(Ta)] <- EWL.ectotherm
  EWL.grid <- Ta.w
  EWL.grid <- setValues(EWL.grid, EWL2)
  #plot(EWL.grid)
  EWL.grid[Tb.grid <= 0] <- NA
  #map('world', add = TRUE)

  writeRaster(EWL.grid, file = paste0('EWL_',month,'.nc'), overwrite = TRUE)
} 

## +2C ## ---------------------------------------
tmax_full_2C <- raster::brick(file.path(spatial_path, 'TerraClimate2C_tmax.nc')) # 2m, deg C
es_kPa_2C    <- tmax_full_2C
values(es_kPa_2C) <- 0.611 * exp(2500000 / 461.5 * ( 1 / 273 - 1 / (values(tmax_full_2C) + 273.15)))

# Actual vapour pressure
ea_kPa <- raster::brick(file.path(spatial_path, 'TerraClimate19812010_vap.nc'))
ea_kPa_2C <- ea_kPa
values(ea_kPa_2C) <- values(ea_kPa_2C) * 0.9

# Calculate VPD (kPa)
vpd_full_2C <- ea_kPa_2C
values(vpd_full_2C) <- values(es_kPa_2C) - values(ea_kPa_2C)

Tbs <- crop(tmax_full_2C, extent(elev))
EWLs <- Tbs 

# Run ectotherm model for each month and save on local drive (+2C scenario)
for(month in 1:12){
  Ta.w   <- crop(tmax_full_2C[[month]], extent(elev))
  esat   <- VAPPRS(Ta.w)
  e      <- esat - crop(vpd_full_2C[[month]], extent(elev)) * 1000
  RH.w   <- e / esat * 100
  RH.w[RH.w < 0] <- 0
  Wind.w <- crop(ws_full[[month]], extent(elev))
  Vstar  <- 0.4 * Wind.w / log((100 / 0.15) + 1) # friction velocity
  Wind.w <- 2.5 * Vstar * log((1 / 0.15) + 1) # correct for reference height (10 m) to ground level (1 cm) assuming level ground
  # compute atmospheric pressure (kPa)
  P.w <- 101325 * ((1 - (0.0065 * elev / 288)) ^ (1 / 0.190284)) / 1000
  
  Ta  <- getValues(Ta.w)
  RH  <- getValues(RH.w)
  P   <- getValues(P.w)
  Pa  <- getValues(e)
  ws  <- getValues(Wind.w)
  P[!is.na(Ta) & is.na(P)] <- 101.325
  Ta2 <- Ta[!is.na(Ta)]
  RH2 <- RH[!is.na(Ta)]
  P2  <- P[!is.na(Ta)]
  ws2 <- ws[!is.na(Ta)]
  Pa2 <- Pa[!is.na(Ta)]
  
  div <- 10
  Twb <- Ta2[1:floor(length(Ta2) / div)]
  micro_base <- micro_global()
  
  for(k in 1:div){
    micro <- micro_base
    if(k == 1){
      extra <- round(24 - (length(Twb) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb, rep(Ta2[1], extra))
      start <- 1
      end   <- length(Twb)
    }
    if(k > 1 & k < div){
      fact  <- (length(Twb) * (k - 1) + k - 1)
      Twb4  <- Ta2[fact:(fact + length(Twb))]
      extra <- round(24 - (length(Twb4) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb4, rep(Ta2[1], extra))
      start <- fact
      end   <- fact + length(Twb)
    }        
    if(k == div){
      fact  <- (length(Twb) * (k - 1) + k - 1)
      Twb4  <- Ta2[fact:length(Ta2)]
      extra <- round(24 - (length(Twb4) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb4, rep(Ta2[1], extra))
      start <- fact
      end   <- length(Ta2)
    } 
    
    soilnames     <- dimnames(micro$soil)
    metoutnames   <- dimnames(micro$metout)
    tcondnames    <- dimnames(micro$tcond)
    specheatnames <- dimnames(micro$specheat)
    densitnames   <- dimnames(micro$densit)
    plantnames    <- dimnames(micro$plant)
    
    micro$metout   <- t(array(micro$metout[1,], dim = c(ncol(micro$metout), length(Twb4))))
    dimnames(micro$metout) <- metoutnames
    micro$soil     <- t(array(micro$soil[1,], dim = c(ncol(micro$soil), length(Twb4))))
    dimnames(micro$soil) <- soilnames
    micro$tcond    <- t(array(micro$tcond[1,], dim = c(ncol(micro$tcond), length(Twb4))))
    dimnames(micro$tcond) <- tcondnames
    micro$specheat <- t(array(micro$specheat[1,], dim = c(ncol(micro$specheat), length(Twb4))))
    dimnames(micro$specheat) <- specheatnames  
    micro$densit   <- t(array(micro$densit[1,], dim = c(ncol(micro$densit), length(Twb4))))
    dimnames(micro$densit) <- densitnames      
    micro$plant    <- t(array(micro$plant[1,], dim = c(ncol(micro$plant), length(Twb4))))
    dimnames(micro$plant) <- plantnames 
    
    micro$shadmet      <- micro$metout
    micro$shadsoil     <- micro$soil
    micro$humid        <- micro$soil
    micro$shadhumid    <- micro$soil
    micro$soilpot      <- micro$soil
    micro$shadpot      <- micro$soil
    micro$soilmoist    <- micro$soil
    micro$shadmoist    <- micro$soil
    micro$shadtcond    <- micro$tcond
    micro$shaddensit   <- micro$densit
    micro$shadspecheat <- micro$specheat
    micro$shadplant    <- micro$plant
    micro$RAINFALL     <- rep(0, length(Twb4)/24)
    micro$minshade     <- rep(0, length(Twb4)/24)
    micro$maxshade     <- rep(90, length(Twb4)/24)
    micro$nyears       <- ceiling(length(Twb4)/24/365)
    
    # replace first line of microclimate input with air temperature and humidity at which to compute Tw
    micro$metout[1:length(Twb4),c(3,4,14)] <- c(Ta2[start:end], rep(Ta2[1], extra)) # set air and sky temperature
    micro$metout[1:length(Twb4),c(5,6)]    <- c(RH2[start:end], rep(RH2[1], extra)) # set relative humidity
    # micro$metout[1:length(Twb3),c(7,8)] <- 0.05 # set wind speed to low (sensitive to this)
    micro$soil[1:length(Twb4),3] <- c(Ta2[start:end], rep(Ta2[1], extra)) # set surface soil temperature to air temperature
    micro$metout[1:length(Twb4), 2] <- rep(seq(0, 23 * 60, 60), length(Ta2)/24 + 1)[1:length(Twb4)]
    #micro$metout[1:length(Twb3), 1] <- seq(0, 23 * 60, 60)[1:length(Twb3)]
    preshr <- c(P2[start:end], rep(P2[1], extra))*1000          
    
    micro$metout[1:length(Twb4),c(7,8)] <- c(ws2[start:end], rep(ws2[1], extra)) # set wind speed    
    
    # run the ectotherm model 
    message(paste('running ectotherm simulation for month ',month,' for ', length(Twb4),' sites \n'))
    ptm <- proc.time() # Start timing
    gc()
    ecto <- ectotherm(Ww_g = 8.7,
                      live = 0,
                      pct_wet = 87,
                      shape = 4, # frog
                      preshr = preshr)
    message(paste0('runtime ', (proc.time() - ptm)[3], ' seconds')) # Stop the clock
    gc()
    environ <- as.data.frame(ecto$environ)
    masbal <- as.data.frame(ecto$masbal)
    if(k == 1){
      Tb.ectotherm <- environ$TC[1:(nrow(environ) - extra)]
      EWL.ectotherm <- masbal$H2OCut_g[1:(nrow(masbal) - extra)]
    }else{
      Tb.ectotherm <- c(Tb.ectotherm, environ$TC[1:(nrow(environ) - extra)])
      EWL.ectotherm <- c(EWL.ectotherm, masbal$H2OCut_g[1:(nrow(masbal) - extra)])
    }
  }
  Tb2 <- Ta
  Tb2[!is.na(Ta)] <- Tb.ectotherm
  Tb.grid <- Ta.w
  Tb.grid <- setValues(Tb.grid, Tb2)
  #plot(Tb.grid)
  #map('world', add = TRUE)
  
  EWL2 <- Ta
  EWL2[!is.na(Ta)] <- EWL.ectotherm
  EWL.grid <- Ta.w
  EWL.grid <- setValues(EWL.grid, EWL2)
  #plot(EWL.grid)
  EWL.grid[Tb.grid <= 0] <- NA
  #map('world', add = TRUE)
  
  writeRaster(EWL.grid, file = paste0('EWL_',month,'_2C.nc'), overwrite=TRUE)
}  

## +4C ## ---------------------------------------
# Saturated vapour pressure
tmax_full_4C <- raster::brick(file.path(spatial_path, 'TerraClimate4C_tmax.nc')) # 2m, deg C
es_kPa_4C    <- tmax_full_4C
values(es_kPa_4C) <- 0.611 * exp(2500000 / 461.5 * ( 1 / 273 - 1 / (values(tmax_full_4C) + 273.15)))

# Actual vapour pressure
ea_kPa      <- raster::brick(file.path(spatial_path, 'TerraClimate19812010_vap.nc'))
ea_kPa_4C   <- ea_kPa
values(ea_kPa_4C) <- values(ea_kPa_4C) * 0.8

# Calculate VPD (kPa)
vpd_full_4C <- ea_kPa_4C
values(vpd_full_4C) <- values(es_kPa_4C) - values(ea_kPa_4C)

Tbs  <- crop(tmax_full_4C, extent(elev))
EWLs <- Tbs 

# Run ectotherm model for each month and save on local drive (+4C scenario)
for(month in 1:12){
  Ta.w   <- crop(tmax_full_4C[[month]], extent(elev))
  esat   <- VAPPRS(Ta.w)
  e      <- esat - crop(vpd_full_4C[[month]], extent(elev)) * 1000
  RH.w   <- e / esat * 100
  RH.w[RH.w < 0] <- 0
  Wind.w <- crop(ws_full[[month]], extent(elev))
  Vstar  <- 0.4 * Wind.w / log((100 / 0.15) + 1) # friction velocity
  Wind.w <- 2.5 * Vstar * log((1 / 0.15) + 1) # correct for reference height (10 m) to ground level (1 cm) assuming level ground
  # compute atmospheric pressure (kPa)
  P.w <- 101325 * ((1 - (0.0065 * elev / 288)) ^ (1 / 0.190284)) / 1000
  
  Ta  <- getValues(Ta.w)
  RH  <- getValues(RH.w)
  P   <- getValues(P.w)
  Pa  <- getValues(e)
  ws  <- getValues(Wind.w)
  P[!is.na(Ta) & is.na(P)] <- 101.325
  Ta2 <- Ta[!is.na(Ta)]
  RH2 <- RH[!is.na(Ta)]
  P2  <- P[!is.na(Ta)]
  ws2 <- ws[!is.na(Ta)]
  Pa2 <- Pa[!is.na(Ta)]
  
  div <- 10
  Twb <- Ta2[1:floor(length(Ta2) / div)]
  micro_base <- micro_global()
  
  for(k in 1:div){
    micro <- micro_base
    if(k == 1){
      extra <- round(24 - (length(Twb) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb, rep(Ta2[1], extra))
      start <- 1
      end   <- length(Twb)
    }
    if(k > 1 & k < div){
      fact  <- (length(Twb) * (k - 1) + k - 1)
      Twb4  <- Ta2[fact:(fact + length(Twb))]
      extra <- round(24 - (length(Twb4) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb4, rep(Ta2[1], extra))
      start <- fact
      end   <- fact + length(Twb)
    }        
    if(k == div){
      fact  <- (length(Twb) * (k - 1) + k - 1)
      Twb4  <- Ta2[fact:length(Ta2)]
      extra <- round(24 - (length(Twb4) / 24)%%1 * 24, 0)
      Twb4  <- c(Twb4, rep(Ta2[1], extra))
      start <- fact
      end   <- length(Ta2)
    } 
    
    soilnames     <- dimnames(micro$soil)
    metoutnames   <- dimnames(micro$metout)
    tcondnames    <- dimnames(micro$tcond)
    specheatnames <- dimnames(micro$specheat)
    densitnames   <- dimnames(micro$densit)
    plantnames    <- dimnames(micro$plant)
    
    micro$metout   <- t(array(micro$metout[1,], dim = c(ncol(micro$metout), length(Twb4))))
    dimnames(micro$metout) <- metoutnames
    micro$soil     <- t(array(micro$soil[1,], dim = c(ncol(micro$soil), length(Twb4))))
    dimnames(micro$soil) <- soilnames
    micro$tcond    <- t(array(micro$tcond[1,], dim = c(ncol(micro$tcond), length(Twb4))))
    dimnames(micro$tcond) <- tcondnames
    micro$specheat <- t(array(micro$specheat[1,], dim = c(ncol(micro$specheat), length(Twb4))))
    dimnames(micro$specheat) <- specheatnames  
    micro$densit   <- t(array(micro$densit[1,], dim = c(ncol(micro$densit), length(Twb4))))
    dimnames(micro$densit) <- densitnames      
    micro$plant    <- t(array(micro$plant[1,], dim = c(ncol(micro$plant), length(Twb4))))
    dimnames(micro$plant) <- plantnames 
    
    micro$shadmet      <- micro$metout
    micro$shadsoil     <- micro$soil
    micro$humid        <- micro$soil
    micro$shadhumid    <- micro$soil
    micro$soilpot      <- micro$soil
    micro$shadpot      <- micro$soil
    micro$soilmoist    <- micro$soil
    micro$shadmoist    <- micro$soil
    micro$shadtcond    <- micro$tcond
    micro$shaddensit   <- micro$densit
    micro$shadspecheat <- micro$specheat
    micro$shadplant    <- micro$plant
    micro$RAINFALL     <- rep(0, length(Twb4)/24)
    micro$minshade     <- rep(0, length(Twb4)/24)
    micro$maxshade     <- rep(90, length(Twb4)/24)
    micro$nyears       <- ceiling(length(Twb4)/24/365)
    
    # replace first line of microclimate input with air temperature and humidity at which to compute Tw
    micro$metout[1:length(Twb4),c(3,4,14)] <- c(Ta2[start:end], rep(Ta2[1], extra)) # set air and sky temperature
    micro$metout[1:length(Twb4),c(5,6)]    <- c(RH2[start:end], rep(RH2[1], extra)) # set relative humidity
    # micro$metout[1:length(Twb3),c(7,8)] <- 0.05 # set wind speed to low (sensitive to this)
    micro$soil[1:length(Twb4),3] <- c(Ta2[start:end], rep(Ta2[1], extra)) # set surface soil temperature to air temperature
    micro$metout[1:length(Twb4), 2] <- rep(seq(0, 23 * 60, 60), length(Ta2)/24 + 1)[1:length(Twb4)]
    #micro$metout[1:length(Twb3), 1] <- seq(0, 23 * 60, 60)[1:length(Twb3)]
    preshr <- c(P2[start:end], rep(P2[1], extra))*1000          
    
    micro$metout[1:length(Twb4),c(7,8)] <- c(ws2[start:end], rep(ws2[1], extra)) # set wind speed    
    
    # run the ectotherm model 
    message(paste('running ectotherm simulation for month ',month,' for ', length(Twb4),' sites \n'))
    ptm <- proc.time() # Start timing
    gc()
    ecto <- ectotherm(Ww_g = 8.7,
                      live = 0,
                      pct_wet = 87,
                      shape = 4, # frog
                      preshr = preshr)
    message(paste0('runtime ', (proc.time() - ptm)[3], ' seconds')) # Stop the clock
    gc()
    environ <- as.data.frame(ecto$environ)
    masbal <- as.data.frame(ecto$masbal)
    if(k == 1){
      Tb.ectotherm <- environ$TC[1:(nrow(environ) - extra)]
      EWL.ectotherm <- masbal$H2OCut_g[1:(nrow(masbal) - extra)]
    }else{
      Tb.ectotherm <- c(Tb.ectotherm, environ$TC[1:(nrow(environ) - extra)])
      EWL.ectotherm <- c(EWL.ectotherm, masbal$H2OCut_g[1:(nrow(masbal) - extra)])
    }
  }
  Tb2 <- Ta
  Tb2[!is.na(Ta)] <- Tb.ectotherm
  Tb.grid <- Ta.w
  Tb.grid <- setValues(Tb.grid, Tb2)
  #plot(Tb.grid)
  #map('world', add = TRUE)
  
  EWL2 <- Ta
  EWL2[!is.na(Ta)] <- EWL.ectotherm
  EWL.grid <- Ta.w
  EWL.grid <- setValues(EWL.grid, EWL2)
  #plot(EWL.grid)
  EWL.grid[Tb.grid <= 0] <- NA
  #map('world', add = TRUE)
  
  writeRaster(EWL.grid, file = paste0('EWL_',month,'_4C.nc'), overwrite=TRUE)
}  

Create plots for main text figure 3.

# Import the downloaded files
EWL_jan <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_1.nc")),
    anuran_sr)
EWL_feb <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_2.nc")),
    anuran_sr)
EWL_mar <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_3.nc")),
    anuran_sr)
EWL_apr <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_4.nc")),
    anuran_sr)
EWL_may <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_5.nc")),
    anuran_sr)
EWL_jun <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_6.nc")),
    anuran_sr)
EWL_jul <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_7.nc")),
    anuran_sr)
EWL_aug <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_8.nc")),
    anuran_sr)
EWL_sep <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_9.nc")),
    anuran_sr)
EWL_oct <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_10.nc")),
    anuran_sr)
EWL_nov <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_11.nc")),
    anuran_sr)
EWL_dec <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_12.nc")),
    anuran_sr)

EWL_jan_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_1_2C.nc")),
    anuran_sr)
EWL_feb_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_2_2C.nc")),
    anuran_sr)
EWL_mar_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_3_2C.nc")),
    anuran_sr)
EWL_apr_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_4_2C.nc")),
    anuran_sr)
EWL_may_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_5_2C.nc")),
    anuran_sr)
EWL_jun_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_6_2C.nc")),
    anuran_sr)
EWL_jul_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_7_2C.nc")),
    anuran_sr)
EWL_aug_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_8_2C.nc")),
    anuran_sr)
EWL_sep_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_9_2C.nc")),
    anuran_sr)
EWL_oct_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_10_2C.nc")),
    anuran_sr)
EWL_nov_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_11_2C.nc")),
    anuran_sr)
EWL_dec_2C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_12_2C.nc")),
    anuran_sr)

EWL_jan_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_1_4C.nc")),
    anuran_sr)
EWL_feb_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_2_4C.nc")),
    anuran_sr)
EWL_mar_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_3_4C.nc")),
    anuran_sr)
EWL_apr_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_4_4C.nc")),
    anuran_sr)
EWL_may_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_5_4C.nc")),
    anuran_sr)
EWL_jun_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_6_4C.nc")),
    anuran_sr)
EWL_jul_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_7_4C.nc")),
    anuran_sr)
EWL_aug_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_8_4C.nc")),
    anuran_sr)
EWL_sep_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_9_4C.nc")),
    anuran_sr)
EWL_oct_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_10_4C.nc")),
    anuran_sr)
EWL_nov_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_11_4C.nc")),
    anuran_sr)
EWL_dec_4C <- raster::projectRaster(raster::stack(file.path(spatial_path, "EWL_12_4C.nc")),
    anuran_sr)

# Combine all
EWL_all <- raster::stack(EWL_jan, EWL_feb, EWL_mar, EWL_apr, EWL_may, EWL_jun, EWL_jul,
    EWL_aug, EWL_sep, EWL_oct, EWL_nov, EWL_dec)

EWL_all_2C <- raster::stack(EWL_jan_2C, EWL_feb_2C, EWL_mar_2C, EWL_apr_2C, EWL_may_2C,
    EWL_jun_2C, EWL_jul_2C, EWL_aug_2C, EWL_sep_2C, EWL_oct_2C, EWL_nov_2C, EWL_dec_2C)

EWL_all_4C <- raster::stack(EWL_jan_4C, EWL_feb_4C, EWL_mar_4C, EWL_apr_4C, EWL_may_4C,
    EWL_jun_4C, EWL_jul_4C, EWL_aug_4C, EWL_sep_4C, EWL_oct_4C, EWL_nov_4C, EWL_dec_4C)

EWL_all_mean <- raster::calc(EWL_all, fun = mean, na.rm = TRUE)
EWL_all_mean_2C <- raster::calc(EWL_all_2C, fun = mean, na.rm = TRUE)
EWL_all_mean_4C <- raster::calc(EWL_all_4C, fun = mean, na.rm = TRUE)

EWL_diff_2C <- raster::overlay(x = EWL_all_mean, y = EWL_all_mean_2C, fun = function(x,
    y) {
    return(y - x)
})

EWL_diff_4C <- raster::overlay(x = EWL_all_mean, y = EWL_all_mean_4C, fun = function(x,
    y) {
    return(y - x)
})

EWL_risk_rob <- raster::projectRaster(raster::stack(EWL_all_mean, anuran_sr, aquatic_sr,
    arboreal_sr, fossorial_sr, ground_sr, semi_aq_sr, stream_sr), crs = rob_proj)
EWL_risk_rob_2C <- raster::projectRaster(raster::stack(EWL_diff_2C, anuran_sr), crs = rob_proj)
EWL_risk_rob_4C <- raster::projectRaster(raster::stack(EWL_diff_4C, anuran_sr), crs = rob_proj)

EWL_sp_df <- raster::as.data.frame(raster::rasterToPoints(EWL_risk_rob)) %>%
    rename(EWL = layer.1, species_n = layer.2, aqua_sp = layer.3, arbo_sp = layer.4,
        foss_sp = layer.5, gron_sp = layer.6, semi_sp = layer.7, strm_sp = layer.8) %>%
    drop_na(species_n)

EWL_sp_2C_df <- raster::as.data.frame(raster::rasterToPoints(EWL_risk_rob_2C)) %>%
    rename(EWL_diff = layer.1, species_n = layer.2) %>%
    drop_na(species_n)

EWL_sp_4C_df <- raster::as.data.frame(raster::rasterToPoints(EWL_risk_rob_4C)) %>%
    rename(EWL_diff = layer.1, species_n = layer.2) %>%
    drop_na(species_n)

# Fig. 3a
EWL_cur_plot <- EWL_sp_df %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = EWL)) + geom_polygon(data = world_rob,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_continuous_sequential(palette = "YlGnBu", rev = T, name = expression("EWL" ~
        ("g" ~ H[2] * O ~ h^{
            "-1"
        }))) + ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-6100000,
    8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07),
    expand = c(0, 0)) + guides(fill = guide_colourbar(barwidth = 20, barheight = 0.2,
    label.position = "bottom")) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10),
    legend.title = element_text(size = 8), legend.position = "bottom") + coord_fixed(ratio = 1)  # fixed ratio

# Fig. 3b - Species richness and EWL
EWL_sp_plot <- EWL_sp_df %>%
    ggplot(aes(x = EWL, y = species_n)) + geom_point(colour = "grey") + xlab(expression("EWL" ~
    ("g" ~ H[2] * O ~ h^{
        "-1"
    }))) + ylab("Species richness") + scale_y_continuous(expand = c(0, 0)) + scale_x_continuous(breaks = seq(0,
    3, 0.5), expand = c(0, 0)) + mytheme()

# Fig. 3c +2C
EWL_2C_plot <- EWL_sp_2C_df %>%
    dplyr::mutate(EWL_diff_cat = case_when(EWL_diff == 0 ~ "0", EWL_diff > 0 & EWL_diff <=
        1 ~ "<1", EWL_diff >= 1 & EWL_diff < 1.5 ~ ">1 to 1.5", EWL_diff >= 1.5 &
        EWL_diff < 2 ~ ">1.5 to 2", EWL_diff >= 2 & EWL_diff < 2.5 ~ ">2 to 2.5",
        EWL_diff >= 2.5 & EWL_diff < 3 ~ ">2.5 to 3", EWL_diff > 3 ~ ">3"), EWL_diff = na_if(EWL_diff,
        0), EWL_diffcat = factor(EWL_diff_cat, levels = c(">3", "<2.5 to 3", ">2 to 2.5",
        "1.5 to 2", ">1 to 1.5", "<1"))) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = EWL_diff_cat)) + geom_polygon(data = world_rob,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#E2E6BD", "#E7CB47", "#EAAB28", "#E78A38", "#DF6753",
        "#D33F6A"), na.translate = F, name = expression(Delta * "EWL" ~ ("g" ~ H[2] *
        O ~ h^{
        "-1"
    }))) + ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-6100000,
    8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07),
    expand = c(0, 0)) + guides(fill = guide_colourbar(barwidth = 20, barheight = 0.2,
    label.position = "bottom")) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10),
    legend.title = element_text(size = 8), legend.position = "bottom") + coord_fixed(ratio = 1)  # fixed ratio

# Fig. 3d +4C
EWL_4C_plot <- EWL_sp_4C_df %>%
    dplyr::mutate(EWL_diff_cat = case_when(EWL_diff == 0 ~ "0", EWL_diff > 0 & EWL_diff <=
        1 ~ "<1", EWL_diff >= 1 & EWL_diff < 1.5 ~ ">1 to 1.5", EWL_diff >= 1.5 &
        EWL_diff < 2 ~ ">1.5 to 2", EWL_diff >= 2 & EWL_diff < 2.5 ~ ">2 to 2.5",
        EWL_diff >= 2.5 & EWL_diff < 3 ~ ">2.5 to 3", EWL_diff > 3 ~ ">3"), EWL_diff = na_if(EWL_diff,
        0), EWL_diffcat = factor(EWL_diff_cat, levels = c(">3", "<2.5 to 3", ">2 to 2.5",
        "1.5 to 2", ">1 to 1.5", "<1"))) %>%
    ggplot() + geom_raster(aes(y = y, x = x, fill = EWL_diff_cat)) + geom_polygon(data = world_rob,
    aes(x = long, y = lat, group = group), colour = "#64686b", fill = NA, size = 0.1) +
    scale_fill_manual(values = c("#E2E6BD", "#E7CB47", "#EAAB28", "#E78A38", "#DF6753",
        "#D33F6A"), na.translate = F, name = expression(Delta * "EWL" ~ ("g" ~ H[2] *
        O ~ h^{
        "-1"
    }))) + ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + scale_y_continuous(limits = c(-6100000,
    8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07),
    expand = c(0, 0)) + guides(fill = guide_colourbar(barwidth = 20, barheight = 0.2,
    label.position = "bottom")) + theme_void() + ylab(NULL) + xlab(NULL) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10),
    legend.title = element_text(size = 8), legend.position = "bottom") + coord_fixed(ratio = 1)  # fixed ratio

cowplot::plot_grid(EWL_cur_plot, EWL_sp_plot, EWL_2C_plot, EWL_4C_plot, ncol = 2,
    align = "h", axis = "bt", labels = c("a", "b", "c", "d"))

Figure 4 - Activity risk

Create plots for main text figure 4.

shad_plot <- shad_model %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + viridis::scale_fill_viridis(option = "magma") +
    # scale_fill_continuous_diverging(palette = 'Blue-Red 3', mid = 12, rev =
    # TRUE) +
ylab(NULL) + xlab("Day of the year") + scale_x_continuous(breaks = seq(0, 365, 50),
    expand = c(0, 0)) + mytheme() + theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

tree_plot <- tree_model %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + viridis::scale_fill_viridis(option = "magma") +
    # scale_fill_continuous_diverging(palette = 'Blue-Red 3', mid = 12, rev =
    # TRUE) +
ylab(NULL) + xlab("Day of the year") + scale_x_continuous(breaks = seq(0, 365, 50),
    expand = c(0, 0)) + mytheme() + theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

burr_plot <- burr_model %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + viridis::scale_fill_viridis(option = "magma") +
    # scale_fill_continuous_diverging(palette = 'Blue-Red 3', mid = 12, rev =
    # TRUE) +
ylab(NULL) + xlab("Day of the year") + scale_x_continuous(breaks = seq(0, 365, 50),
    expand = c(0, 0)) + mytheme() + theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

prow_2 <- cowplot::plot_grid(shad_plot + theme(legend.position = "none"), tree_plot +
    theme(legend.position = "none"), burr_plot + theme(legend.position = "none"),
    ncol = 1, labels = c("a", "c", "e"), align = "v", axis = "l")

legend_b_2 <- cowplot::get_legend(burr_plot + guides(color = guide_legend(nrow = 1)))
top_graph <- cowplot::plot_grid(prow_2, legend_b_2, ncol = 1, rel_heights = c(1,
    0.1))

# Relative change
shad_diff_model <- shad_curr_wet_df %>%
    merge(shad_curr_dry_df, by = "day") %>%
    merge(shad_warm_wet_df, by = "day") %>%
    merge(shad_warm_dry_df, by = "day") %>%
    dplyr::mutate(curr_dry_diff = curr_dry - curr_wet, warm_wet_diff = warm_wet -
        curr_wet, warm_dry_diff = warm_dry - curr_wet) %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::filter(condition == c("curr_dry_diff", "warm_wet_diff", "warm_dry_diff")) %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry_diff", "warm_wet_diff",
        "curr_dry_diff"))) %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + scale_fill_continuous_diverging(palette = "Blue-Red 3",
    mid = 0, rev = TRUE, limits = c(-15, 15)) + ylab(NULL) + xlab("Day of the year") +
    scale_x_continuous(breaks = seq(0, 365, 50), expand = c(0, 0)) + mytheme() +
    theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

tree_diff_model <- tree_curr_wet_df %>%
    merge(tree_curr_dry_df, by = "day") %>%
    merge(tree_warm_wet_df, by = "day") %>%
    merge(tree_warm_dry_df, by = "day") %>%
    dplyr::mutate(curr_dry_diff = curr_dry - curr_wet, warm_wet_diff = warm_wet -
        curr_wet, warm_dry_diff = warm_dry - curr_wet) %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::filter(condition == c("curr_dry_diff", "warm_wet_diff", "warm_dry_diff")) %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry_diff", "warm_wet_diff",
        "curr_dry_diff"))) %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + scale_fill_continuous_diverging(palette = "Blue-Red 3",
    mid = 0, rev = TRUE, limits = c(-15, 15)) + ylab(NULL) + xlab("Day of the year") +
    scale_x_continuous(breaks = seq(0, 365, 50), expand = c(0, 0)) + mytheme() +
    theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

burr_diff_model <- burr_curr_wet_df %>%
    merge(burr_curr_dry_df, by = "day") %>%
    merge(burr_warm_wet_df, by = "day") %>%
    merge(burr_warm_dry_df, by = "day") %>%
    dplyr::mutate(curr_dry_diff = curr_dry - curr_wet, warm_wet_diff = warm_wet -
        curr_wet, warm_dry_diff = warm_dry - curr_wet) %>%
    pivot_longer(!day, names_to = "condition", values_to = "hours") %>%
    dplyr::filter(condition == c("curr_dry_diff", "warm_wet_diff", "warm_dry_diff")) %>%
    dplyr::mutate(condition = factor(condition, levels = c("warm_dry_diff", "warm_wet_diff",
        "curr_dry_diff"))) %>%
    ggplot(aes(x = day, y = condition, fill = hours)) + geom_tile() + scale_fill_continuous_diverging(palette = "Blue-Red 3",
    mid = 0, rev = TRUE, limits = c(-15, 15)) + ylab(NULL) + xlab("Day of the year") +
    scale_x_continuous(breaks = seq(0, 365, 50), expand = c(0, 0)) + mytheme() +
    theme(legend.position = "bottom") + guides(fill = guide_colourbar(barheight = 0.5,
    barwidth = 5, label.position = "bottom"))

bot_graph <- cowplot::plot_grid(shad_diff_model, tree_diff_model, burr_diff_model,
    ncol = 1, labels = c("b", "d", "g"), align = "v", axis = "l")

cowplot::plot_grid(top_graph, bot_graph)

Extended data

Extended Figure 1 - PDSI intensity risk

PDSI_2C_diff_rast_crop <- raster::mask(crop(PDSI_2C_diff_rast, extent(world)), world)  # crop 
PDSI_2C_rob <- raster::projectRaster(raster::stack(PDSI_2C_diff_rast_crop, resample(anuran_sr,
    PDSI_2C_diff_rast_crop)), crs = rob_proj)

PDSI_4C_diff_rast_crop <- raster::mask(crop(PDSI_4C_diff_rast, extent(world)), world)  # crop 
PDSI_4C_rob <- raster::projectRaster(raster::stack(PDSI_4C_diff_rast_crop, resample(anuran_sr,
    PDSI_4C_diff_rast_crop)), crs = rob_proj)

PDSI_2C_df_rob <- raster::as.data.frame(raster::rasterToPoints(PDSI_2C_rob)) %>%
    dplyr::rename(layer = delta_int_2C, species_n = layer) %>%
    dplyr::mutate(change = case_when(layer >= 4 ~ "4", layer >= 3 & layer < 4 ~ "3",
        layer >= 2 & layer < 3 ~ "2", layer >= 1 & layer < 2 ~ "1", layer >= -1 &
            layer < 1 ~ "0", layer >= -2 & layer < -1 ~ "-1", layer >= -3 & layer <
            -2 ~ "-2", layer >= -4 & layer < -3 ~ "-3", layer < -4 ~ "-4")) %>%
    dplyr::mutate(change = factor(change, levels = c("-4", "-3", "-2", "-1", "0",
        "1", "2", "3", "4"), ordered = TRUE)) %>%
    dplyr::filter(change != "NA" & species_n != "NA")

PDSI_4C_df_rob <- raster::as.data.frame(raster::rasterToPoints(PDSI_4C_rob)) %>%
    dplyr::rename(layer = delta_int_4C, species_n = layer) %>%
    dplyr::mutate(change = case_when(layer >= 4 ~ "4", layer >= 3 & layer < 4 ~ "3",
        layer >= 2 & layer < 3 ~ "2", layer >= 1 & layer < 2 ~ "1", layer >= -1 &
            layer < 1 ~ "0", layer >= -2 & layer < -1 ~ "-1", layer >= -3 & layer <
            -2 ~ "-2", layer >= -4 & layer < -3 ~ "-3", layer < -4 ~ "-4")) %>%
    dplyr::mutate(change = factor(change, levels = c("-4", "-3", "-2", "-1", "0",
        "1", "2", "3", "4"), ordered = TRUE)) %>%
    dplyr::filter(change != "NA" & species_n != "NA")

# Intensity +2C - Ex Fig. 1a
colours_PDSI <- RColorBrewer::brewer.pal(9, "RdBu")
PDSI_2C_plot <- ggplot() + geom_raster(data = PDSI_2C_df_rob, aes(y = y, x = x, fill = change)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = colours_PDSI) + ggnewscale::new_scale("fill") +
    geom_raster(data = hill_df %>%
        filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression(Delta * "PDSI intensity (+2°C)")) +
    scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07,
    1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

# Intensity +4C - Ex Fig. 1c
PDSI_4C_plot <- ggplot() + geom_raster(data = PDSI_4C_df_rob, aes(y = y, x = x, fill = change)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = colours_PDSI) + ggnewscale::new_scale("fill") +
    geom_raster(data = hill_df %>%
        filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression(Delta * "PDSI intensity (+4°C)")) +
    scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0, 0)) + scale_x_continuous(limits = c(-1.5e+07,
    1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(), axis.text = element_blank(),
    axis.ticks = element_blank(), plot.title = element_text(size = 10)) + coord_fixed(ratio = 1)  # fixed ratio

# 2C change - Ex Fig 1b
PDSI_sp_2C_plot <- PDSI_sp_2C %>%
    rows_insert(tibble(change_2C = "4", all_freq = 0), conflict = "ignore") %>%
    filter(change_2C != "NA") %>%
    ggplot(aes(x = change_2C, y = all_freq, fill = change_2C)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = colours_PDSI) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("PDSI") + ylim(0, 80) +
    ggtitle("Grid cell occupied +2°C") + mytheme() + theme(plot.title = element_text(size = 10))

# 4C change - Ex Fig 1d
PDSI_sp_4C_plot <- PDSI_sp_4C %>%
    filter(change_4C != "NA") %>%
    ggplot(aes(x = change_4C, y = all_freq, fill = change_4C)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = colours_PDSI) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("PDSI") + ylim(0, 80) +
    ggtitle("Grid cell occupied +4°C") + mytheme() + theme(plot.title = element_text(size = 10))

left_plot <- cowplot::plot_grid(PDSI_2C_plot + theme(legend.position = "none"), PDSI_4C_plot +
    theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt", labels = c("a",
    "c", "e"))

right_plot <- cowplot::plot_grid(PDSI_sp_2C_plot + theme(legend.position = "none"),
    PDSI_sp_4C_plot + theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt",
    labels = c("b", "d", "f"))

cowplot::plot_grid(left_plot, right_plot, ncol = 2, rel_widths = c(1, 0.7))

Extended Figure 2 - PDSI frequency risk

freq_diff_rast_crop <- raster::mask(crop(freq_diff_rast, extent(world)), world)  # crop

PDSI_freq_rob <- raster::projectRaster(raster::stack(freq_diff_rast_crop, resample(anuran_sr,
    freq_diff_rast_crop)), crs = rob_proj)

PDSI_freq_2C_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_freq_rob)) %>%
    dplyr::mutate(diff_2C_cat = case_when(diff_2C >= 10 ~ "10-12", diff_2C >= 8 &
        diff_2C < 10 ~ "8-10", diff_2C >= 6 & diff_2C < 8 ~ "6-8", diff_2C >= 4 &
        diff_2C < 6 ~ "4-6", diff_2C >= 2 & diff_2C < 4 ~ "2-4", diff_2C >= 1 & diff_2C <
        2 ~ "1-2", diff_2C > 0 & diff_2C < 1 ~ "0-1", diff_2C >= -1 & diff_2C < 0 ~
        "-0-1", diff_2C >= -2 & diff_2C < -1 ~ "-1-2", diff_2C >= -4 & diff_2C <
        -2 ~ "-2-4")) %>%
    dplyr::mutate(diff_2C_cat = factor(diff_2C_cat, levels = c("10-12", "8-10", "6-8",
        "4-6", "2-4", "1-2", "0-1", "-0-1", "-1-2", "-2-4"), ordered = TRUE)) %>%
    dplyr::filter(diff_2C_cat != "NA" & layer != "NA")

PDSI_freq_4C_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_freq_rob)) %>%
    dplyr::mutate(diff_4C_cat = case_when(diff_4C >= 10 ~ "10-12", diff_4C >= 8 &
        diff_4C < 10 ~ "8-10", diff_4C >= 6 & diff_4C < 8 ~ "6-8", diff_4C >= 4 &
        diff_4C < 6 ~ "4-6", diff_4C >= 2 & diff_4C < 4 ~ "2-4", diff_4C >= 1 & diff_4C <
        2 ~ "1-2", diff_4C > 0 & diff_4C < 1 ~ "0-1", diff_4C >= -1 & diff_4C < 0 ~
        "-0-1", diff_4C >= -2 & diff_4C < -1 ~ "-1-2", diff_4C >= -4 & diff_4C <
        -2 ~ "-2-4")) %>%
    dplyr::mutate(diff_4C_cat = factor(diff_4C_cat, levels = c("10-12", "8-10", "6-8",
        "4-6", "2-4", "1-2", "0-1", "-0-1", "-1-2", "-2-4"), ordered = TRUE)) %>%
    dplyr::filter(diff_4C_cat != "NA" & layer != "NA")

# Freq map 2C - Fig S10a
freq_2C_plot <- ggplot() + geom_raster(data = PDSI_freq_2C_df, aes(y = y, x = x,
    fill = diff_2C_cat)) + geom_polygon(data = world_rob, aes(x = long, y = lat,
    group = group), colour = "#64686b", fill = NA, size = 0.1) + scale_fill_manual(values = c("#67001F",
    "#B2182B", "#D6604D", "#F4A582", "#FDDBC7", "#FAE9DF", "#F7F7F7", "#dfebf2")) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in drought frequency (" *
    Delta * "PDSI +2°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)  # fixed ratio

# Freq map 4C - Fig S10c
freq_4C_plot <- ggplot() + geom_raster(data = PDSI_freq_4C_df, aes(y = y, x = x,
    fill = diff_4C_cat)) + geom_polygon(data = world_rob, aes(x = long, y = lat,
    group = group), colour = "#64686b", fill = NA, size = 0.1) + scale_fill_manual(values = c("#67001F",
    "#B2182B", "#D6604D", "#F4A582", "#FDDBC7", "#FAE9DF", "#F7F7F7", "#dfebf2")) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in drought frequency (" *
    Delta * "PDSI +4°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)  # fixed ratio

# 2C change - Fig S10b
freq_sp_2C <- data.frame(PDSI_freq_2C_df %>%
    dplyr::group_by(diff_2C_cat) %>%
    dplyr::summarise(species_n = length(layer[!is.na(layer)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100)

freq_sp_2C_plot <- freq_sp_2C %>%
    ggplot(aes(x = diff_2C_cat, y = all_freq, fill = diff_2C_cat)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7", "#dfebf2")) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("Months") + ylim(0, 60) +
    ggtitle("Grid cell occupied +2°C") + mytheme() + theme(plot.title = element_text(size = 10))

# 4C change - Fig S10d
freq_sp_4C <- data.frame(PDSI_freq_4C_df %>%
    dplyr::group_by(diff_4C_cat) %>%
    dplyr::summarise(species_n = length(layer[!is.na(layer)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100)

freq_sp_4C_plot <- freq_sp_4C %>%
    ggplot(aes(x = diff_4C_cat, y = all_freq, fill = diff_4C_cat)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7", "#dfebf2")) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("Months") + ylim(0, 60) +
    ggtitle("Grid cell occupied +4°C") + mytheme() + theme(plot.title = element_text(size = 10))

left_plot2 <- cowplot::plot_grid(freq_2C_plot + theme(legend.position = "none"),
    freq_4C_plot + theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt",
    labels = c("a", "c"))

right_plot2 <- cowplot::plot_grid(freq_sp_2C_plot + theme(legend.position = "none"),
    freq_sp_4C_plot + theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt",
    labels = c("b", "d"))

cowplot::plot_grid(left_plot2, right_plot2, ncol = 2, rel_widths = c(1, 0.7))

Extended Figure 3 - PDSI duration risk

PDSI_dur_diff_crop <- raster::mask(crop(PDSI_dur_diff, extent(world)), world)  # crop

PDSI_dur_rob <- raster::projectRaster(raster::stack(PDSI_dur_diff_crop, resample(anuran_sr,
    PDSI_dur_diff_crop)), crs = rob_proj)

PDSI_dur_2C_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_dur_rob)) %>%
    dplyr::rename(sp_n = layer) %>%
    dplyr::filter(!is.na(sp_n)) %>%
    dplyr::mutate(diff_2C_cat = case_when(delta_dur_2C >= 10 ~ ">10", delta_dur_2C >=
        8 & delta_dur_2C < 10 ~ "8-10", delta_dur_2C >= 6 & delta_dur_2C < 8 ~ "6-8",
        delta_dur_2C >= 4 & delta_dur_2C < 6 ~ "4-6", delta_dur_2C >= 2 & delta_dur_2C <
            4 ~ "2-4", delta_dur_2C >= 1 & delta_dur_2C < 2 ~ "1-2", delta_dur_2C >
            0 & delta_dur_2C < 1 ~ "0-1", delta_dur_2C >= -1 & delta_dur_2C < 0 ~
            "-0-1", delta_dur_2C >= -2 & delta_dur_2C < -1 ~ "-1-2", delta_dur_2C >=
            -4 & delta_dur_2C < -2 ~ "-2-4", delta_dur_2C >= -8 & delta_dur_2C <
            -6 ~ "-6-8", delta_dur_2C >= -10 & delta_dur_2C < -8 ~ "-8-10", delta_dur_2C <
            -10 ~ "<-10")) %>%
    dplyr::mutate(diff_2C_cat = factor(diff_2C_cat, levels = c(">10", "8-10", "6-8",
        "4-6", "2-4", "1-2", "0-1", "-0-1", "-1-2", "-2-4", "-4-6", "-6-8", "-8-10",
        "<-10"), ordered = TRUE)) %>%
    dplyr::filter(diff_2C_cat != "NA")

PDSI_dur_4C_df <- raster::as.data.frame(raster::rasterToPoints(PDSI_dur_rob)) %>%
    dplyr::rename(sp_n = layer) %>%
    dplyr::filter(!is.na(sp_n)) %>%
    dplyr::mutate(diff_4C_cat = case_when(delta_dur_4C >= 10 ~ ">10", delta_dur_4C >=
        8 & delta_dur_4C < 10 ~ "8-10", delta_dur_4C >= 6 & delta_dur_4C < 8 ~ "6-8",
        delta_dur_4C >= 4 & delta_dur_4C < 6 ~ "4-6", delta_dur_4C >= 2 & delta_dur_4C <
            4 ~ "2-4", delta_dur_4C >= 1 & delta_dur_4C < 2 ~ "1-2", delta_dur_4C >
            0 & delta_dur_4C < 1 ~ "0-1", delta_dur_4C >= -1 & delta_dur_4C < 0 ~
            "-0-1", delta_dur_4C >= -2 & delta_dur_4C < -1 ~ "-1-2", delta_dur_4C >=
            -4 & delta_dur_4C < -2 ~ "-2-4", delta_dur_4C >= -6 & delta_dur_4C <
            -4 ~ "-4-6", delta_dur_4C >= -8 & delta_dur_4C < -6 ~ "-6-8", delta_dur_4C >=
            -10 & delta_dur_4C < -8 ~ "-8-10", delta_dur_4C < -10 ~ "<-10")) %>%
    dplyr::mutate(diff_4C_cat = factor(diff_4C_cat, levels = c(">10", "8-10", "6-8",
        "4-6", "2-4", "1-2", "0-1", "-0-1", "-1-2", "-2-4", "-4-6", "-6-8", "-8-10",
        "<-10"), ordered = TRUE)) %>%
    dplyr::filter(diff_4C_cat != "NA")

dur_2C_plot <- ggplot() + geom_raster(data = PDSI_dur_2C_df, aes(y = y, x = x, fill = diff_2C_cat)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = c("#67001F", "#B2182B",
    "#D6604D", "#F4A582", "#FDDBC7", "#FAE9DF", "#F7F7F7", "#dfebf2", "#D1E5F0")) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in drought duration (" *
    Delta * "PDSI +2°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)  # fixed ratio

dur_4C_plot <- ggplot() + geom_raster(data = PDSI_dur_4C_df, aes(y = y, x = x, fill = diff_4C_cat)) +
    geom_polygon(data = world_rob, aes(x = long, y = lat, group = group), colour = "#64686b",
        fill = NA, size = 0.1) + scale_fill_manual(values = c("#67001F", "#B2182B",
    "#D6604D", "#F4A582", "#FDDBC7", "#FAE9DF", "#F7F7F7", "#dfebf2", "#D1E5F0")) +
    ggnewscale::new_scale("fill") + geom_raster(data = hill_df %>%
    filter(hill <= 0.645), aes(lon, lat, fill = hill, alpha = hill), show.legend = FALSE) +
    scale_fill_gradient(low = "black", high = "grey") + scale_alpha_continuous(trans = "reverse") +
    theme_void() + ylab(NULL) + xlab(NULL) + ggtitle(expression("Change in drought duration (" *
    Delta * "PDSI +4°C)")) + scale_y_continuous(limits = c(-6100000, 8500000), expand = c(0,
    0)) + scale_x_continuous(limits = c(-1.5e+07, 1.6e+07), expand = c(0, 0)) + theme(axis.title = element_blank(),
    axis.text = element_blank(), axis.ticks = element_blank(), plot.title = element_text(size = 10)) +
    coord_fixed(ratio = 1)  # fixed ratio

# 2C change - Fig S11b
dur_sp_2C <- data.frame(PDSI_dur_2C_df %>%
    dplyr::group_by(diff_2C_cat) %>%
    dplyr::summarise(species_n = length(sp_n[!is.na(sp_n)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100)

dur_sp_2C_plot <- dur_sp_2C %>%
    ggplot(aes(x = diff_2C_cat, y = all_freq, fill = diff_2C_cat)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7", "#dfebf2", "#D1E5F0")) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("Months") + ylim(0, 50) +
    ggtitle("Grid cell occupied +2°C") + mytheme() + theme(plot.title = element_text(size = 10))

# 4C change - Fig S11d
dur_sp_4C <- data.frame(PDSI_dur_4C_df %>%
    dplyr::group_by(diff_4C_cat) %>%
    dplyr::summarise(species_n = length(sp_n[!is.na(sp_n)]))) %>%
    dplyr::mutate(all_freq = species_n/sum(species_n) * 100)

dur_sp_4C_plot <- dur_sp_4C %>%
    ggplot(aes(x = diff_4C_cat, y = all_freq, fill = diff_4C_cat)) + geom_bar(stat = "identity") +
    scale_fill_manual(values = c("#67001F", "#B2182B", "#D6604D", "#F4A582", "#FDDBC7",
        "#FAE9DF", "#F7F7F7", "#dfebf2", "#D1E5F0")) + geom_text(aes(label = round(all_freq,
    1)), vjust = -1, size = 2) + ylab("% species") + xlab("Months") + ylim(0, 50) +
    ggtitle("Grid cell occupied +4°C") + mytheme() + theme(plot.title = element_text(size = 10))

left_plot3 <- cowplot::plot_grid(dur_2C_plot + theme(legend.position = "none"), dur_4C_plot +
    theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt", labels = c("a",
    "c"))

right_plot3 <- cowplot::plot_grid(dur_sp_2C_plot + theme(legend.position = "none"),
    dur_sp_4C_plot + theme(legend.position = "none"), ncol = 1, align = "h", axis = "bt",
    labels = c("b", "d"))

cowplot::plot_grid(left_plot3, right_plot3, ncol = 2, rel_widths = c(1, 0.7))

Extended Figure 4 - Water uptake

hydr_conditions <- list(hydration = setNames(c(70, 80, 90, 100), c(70, 80, 90, 100)))
wu_ce <- conditional_effects(wu_model, effects = "lnMass:hydration", int_conditions = hydr_conditions)

wu_ce <- data.frame(wu_ce[[1]]) %>%
    dplyr::rename(estimate = estimate__, hydration_cal = effect2__) %>%
    dplyr::mutate(mean_mass_g = exp(lnMass), hydration_cal = as.numeric(as.character(hydration_cal)))

wu_dat %>%
    ggplot() + geom_point(aes(x = mean_mass_g, y = mg_h_mean), size = 2, shape = 21,
    fill = "white") + geom_line(data = wu_ce, aes(x = mean_mass_g, y = exp(estimate),
    group = hydration, colour = hydration), size = 1) + geom_text(data = wu_ce %>%
    filter(mean_mass_g == last(mean_mass_g)), aes(label = hydration, x = mean_mass_g +
    50, y = exp(estimate), hjust = -0.01), size = 3) + labs(x = "Body mass (g)",
    colour = "Initial hydration (%)") + ylab(expression("WU" ~ ("mg" ~ H[2] * O ~
    h^{
        "-1"
    }))) + scale_y_continuous(trans = scales::log_trans(), breaks = c(10, 100, 1000,
    10000, 1e+05), labels = c(10, 100, "1,000", "10,000", "100,000")) + scale_x_continuous(trans = "log10") +
    scale_colour_gradient2(low = "#0E3F5C", mid = "#2A6D7A", high = "#8FCCB4", midpoint = 85) +
    expand_limits(x = 500) + mytheme() + theme(legend.title = element_text(size = 8),
    legend.position = "bottom") + guides(colour = guide_colourbar(barheight = 0.5,
    barwidth = 10, title.position = "top"))


Additional figures

temp_dat <- ewl_dat %>%
    dplyr::filter(!is.na(trt_temp))

temp_dat %>%
    ggplot(aes(x = trt_temp, y = skin_temp)) + geom_abline(intercept = 0, slope = 1,
    linetype = "dashed", size = 0.5) + ggpmisc::stat_poly_line(method = "lm", formula = y ~
    x + I(x^6), se = F, color = "black") + ggpmisc::stat_poly_eq(method = "lm", formula = y ~
    x + I(x^6), ggpmisc::use_label(c("eq", "R2", "n"))) + geom_point(size = 2, shape = 21,
    fill = "white") + ylim(5, 50) + xlim(5, 50) + labs(x = "Air temperature (°C)",
    y = "Skin surface temperature (°C)") + mytheme()

Fig. S11. Relationship between exposed air temperature (°C) during the experiment and the observed skin surface temperature (°C) across 238 species. The black line represents the non-linear relationship between air temperature and skin temperature where the skin temperature remains at ~35°C when exposed to air temperatures > 40°C.

raw_dat %>%
    dplyr::filter(trait != "water gain" & !is.na(unit_corrected_mean)) %>%
    ggplot(aes(x = unit_corrected_mean, y = r_s_est, fill = calculated)) + geom_point(size = 2,
    shape = 21, colour = "black") + xlab(expression("EWL" ~ ("mg" ~ "H"[2] * O ~
    h^{
        "-1"
    }))) + ylab(expression(italic("r")["i"] ~ "(s cm"^{
    -1
} * ")")) + labs(fill = expression("Estimated" ~ italic("r")["i"])) + scale_x_log10(breaks = scales::trans_breaks("log10",
    function(x) 10^x), labels = scales::trans_format("log10", scales::math_format(10^.x))) +
    scale_y_log10(breaks = scales::trans_breaks("log10", function(x) 10^x), labels = scales::trans_format("log10",
        scales::math_format(10^.x))) + annotation_logticks() + scale_fill_manual(values = c("white",
    "grey")) + mytheme() + theme(legend.position = "bottom")

Fig. S12. Relationship between evaporative water loss (EWL; mg H2O cm−2 h−1) and resistance to water loss (\(r_i\); s cm-1) on a base-10 logarithmic scale. Measured \(r_i\) from the study presented as white points, and the estimated \(r_i\) from EWL in grey points.

EWL_sp_long <- EWL_sp_df %>%
    dplyr::select(-species_n) %>%
    tidyr::pivot_longer(!c(x, y, EWL), names_to = "ecotype", values_to = "count") %>%
    dplyr::mutate(ecotype = factor(ecotype, levels = c("foss_sp", "gron_sp", "aqua_sp",
        "arbo_sp", "semi_sp", "strm_sp")))

ecotype_labs <- c("Fossorial", "Ground-dwelling", "Aquatic", "Arboreal", "Semi-aquatic",
    "Stream-dwelling")
names(ecotype_labs) <- c("foss_sp", "gron_sp", "aqua_sp", "arbo_sp", "semi_sp", "strm_sp")

EWL_sp_long %>%
    ggplot(aes(x = EWL, y = count)) + geom_point(data = transform(EWL_sp_long, ecotype = NULL),
    colour = "grey85") + geom_point(aes(colour = ecotype), alpha = 0.5, show.legend = F) +
    xlab(expression("EWL" ~ ("g" ~ H[2] * O ~ h^{
        "-1"
    }))) + ylab(NULL) + scale_colour_viridis_d() + scale_y_continuous(expand = c(0,
    0)) + scale_x_continuous(breaks = seq(0, 3, 0.5), expand = c(0, 0)) + facet_wrap(vars(ecotype),
    labeller = labeller(ecotype = ecotype_labs)) + mytheme()

Fig. S13. Relationship between EWL and species richness by ecotype. Grey points represent the total dataset as comparison for where each ecotype fits.


References

Anderson, R. C. O., Bovo, R. P., Eismann, C. E., Menegario, A. A. and Andrade, D. V. (2017). Not good, but not all bad: Dehydration effects on body fluids, organ masses, and water flux through the skin of Rhinella schneideri (Amphibia, Bufonidae). Physiological and Biochemical Zoology 90, 170191.
Baldwin, R. A. (1974). The water balance response of the pelvic “patch” of Bufo punctatus and Bufo boreas. Comparative Biochemistry and Physiology Part A: Physiology 47, 1285–1295.
Blaylock, L. A., Ruibal, R. and Kathryn, P.-A. (1976). Skin structure and wiping behavior of phyllomedusine frogs. Copeia 1976, 283–295.
Bovo, R. P., Simon, M. N., Lyra, M. L., Navas, C. A. and Andrade, D. V. Beyond janzen’s hypothesis: How amphibians that climb tropical mountains respond to climate variation.
Budyko, M. I. (1961). The heat balance of the earth’s surface. Soviet Geography 2, 3–13.
Buttemer, W. A. and Thomas, C. (2003). Influence of temperature on evaporative water loss and cutaneous resistance to water vapour diffusion in the orange-thighed frog (Litoria xanthomera). Australian Journal of Zoology 51, 111–118.
Feder, M. E. and Burggren, W. W. (1992). Environmental physiology of the amphibians. Chicago, USA: University of Chicago Press.
Gomez, N. A., Acosta, M., Zaidan III, F. and Lillywhite, H. B. (2006). Wiping behavior, skin resistance, and the metabolic response to dehydration in the arboreal frog Phyllomedusa hypochondrialis. Current Biology 79, 1058–1068.
Gouveia, S. F., Rafael, R. P., Rubalcaba, J. G., Da Silva, F. R., Maciel, N. M., Andrade, D. V. and Martinez, P. A. (2019). Biophysical modeling of water economy can explain geographic gradient of body size in anurans. The American Naturalist 193, 51–58.
Hillman, S. S., Withers, P. C., Drewes, R. C. and Hillyard, S. D. (2009). Ecological and environmental physiology of amphibians. New York, USA: Oxford University Press.
Jetz, W. and Pyron, R. A. (2018). The interplay of past diversification and evolutionary isolation with present imperilment across the amphibian tree of life. Nature Ecology & Evolution 2, 850–858.
Kearney, M. R. and Porter, W. P. (2017). NicheMapR–an R package for biophysical modelling: The microclimate model. Ecography 40, 664–674.
Kearney, M. R. and Porter, W. P. (2020). NicheMapR–an R package for biophysical modelling: The ectotherm and dynamic energy budget models. Ecography 43, 85–96.
Kearney, M. R., Phillips, B. L., Tracy, C. R., Christian, K. A., Betts, G. and Porter, W. P. (2008). Modelling species distributions without using species distributions: The cane toad in australia under current and future climates. Ecography 31, 423–434.
Kearney, M. R., Shamakhy, A., Tingley, R., Karoly, D. J., Hoffmann, A. A., Briggs, P. R. and Porter, W. P. (2014). Microclimate modelling at macro scales: A test of a general microclimate model integrated with gridded continental‐scale soil and weather data. Methods in Ecology and Evolution 5, 273–286.
Klein, W., Dabés, L., Bonfim, V. M. G., Magrini, L. and Napoli, M. F. (2016). Allometric relationships between cutaneous surface area and body mass in anuran amphibians. Zoologischer Anzeiger-A Journal of Comparative Zoology 263, 45–54.
Kobelt, F. and Linsenmair, K. E. (1986). Adaptations of the reed frog Hyperolius viridiflavus (amphibia, anura, hyperoliidae) to its arid environment i. The skin of Hyperolius viridiflavus nitidulus in wet and dry season conditions. Oecologia 68, 533–541.
Lillywhite, H. B. (2006). Water relations of tetrapod integument. Journal of Experimental Biology 209, 202–226.
McClanahan Jr, L. and Baldwin, R. (1969). Rate of water uptake through the integument of the desert toad, Bufo punctatus. Comparative Biochemistry and Physiology 28, 381–389.
Moen, D. S. and Wiens, J. J. (2017). Microhabitat and climatic niche change explain patterns of diversification among frog families. The American Naturalist 190, 29–44.
Monteith, John and Unsworth, M. (2013). Principles of environmental physics: Plants, animals, and the atmosphere. Oxford, UK: Academic Press.
Ouzzani, M., Hammady, H., Fedorowicz, Z. and Elmagarmid, A. (2016). Rayyan—a web and mobile app for systematic reviews. Systematic reviews 5, 1–10.
Palmer, W. C. (1965). Meteorological drought. Washington DC, USA: US Department of Commerce, Weather Bureau.
Pirtle, E. I., Tracy, C. R. and Kearney, R., Michael (2019). Hydroregulation: A neglected behavioral response of lizards to climate change? In Behavior of lizards, pp. 343–374. New York, USA: CRC Press.
Riddell, E. A., Apanovitch, E. K., Odom, J. P. and Sears, M. W. (2017). Physical calculations of resistance to water loss improve predictions of species range models. Ecological Monographs 87, 21–33.
Senzano, L. M., Bovo, R. P. and Andrade, D. V. (2022). Empirical estimation of skin resistance to water loss in amphibians: Agar evaluation as a non-resistance model to evaporation. Journal of Experimental Biology 225, jeb243941.
Spotila, J. R. and Berman, E. N. (1976). Determination of skin resistance and the role of the skin in controlling water loss in amphibians and reptiles. Comparative Biochemistry and Physiology Part A: Physiology 55, 407–411.
Stull, R. B. and Ahrens, C. D. (2000). Meteorology for scientists and engineers. Second edition. California, USA: Brooks/Cole.
Titon Jr, B. and Gomes, F. R. (2015). Relation between water balance and climatic variables associated with the geographical distribution of anurans. PLOS One 10, e0140761.
Titon Jr, B., Navas, C. A., Jim, J. and Gomes, F. R. (2010). Water balance and locomotor performance in three species of neotropical toads that differ in geographical distribution. Comparative Biochemistry and Physiology Part A: Molecular & Integrative Physiology 156, 129–135.
Tracy, C. R. (1976). A model of the dynamic exchanges of water and energy between a terrestrial amphibian and its environment. Ecological Monographs 46, 293–326.
Tracy, C. R., Welch, W. R., Pinshow, B., Kearney, M. R. and Porter, W. P. (2019). Properties of air: A manual for use in biophysical ecology.
Willumsen, N. J., Viborg, A. L. and Hillyard, S. D. (2007). Vascular aspects of water uptake mechanisms in the toad skin: Perfusion, diffusion, confusion. Comparative Biochemistry and Physiology Part A: Molecular & Integrative Physiology 148, 55–63.
Withers, P. C., Hillman, S. S., Drewes, R. and Sokol, O. (1982). Water loss and nitrogen excretion in sharp-nosed reed frogs (Hyperolius nasutus: Anura, Hyperoliidae). Journal of Experimental Biology 97, 335–343.
Withers, P. C., Hillman, S. S. and Drewes, R. C. (1984). Evaporative water loss and skin lipids of anuran amphibians. Journal of Experimental Zoology 232, 11–17.



Session Information

R version 4.2.2 (2022-10-31)

Platform: aarch64-apple-darwin20 (64-bit)

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: rasterSp(v.0.0.1), tmaptools(v.3.1-1), tmap(v.3.3-4), sf(v.1.0-14), raster(v.3.6-26), sp(v.2.1-1), ncdf4(v.1.21), NicheMapR(v.3.2.1), ggtree(v.3.4.1), phytools(v.1.9-16), maps(v.3.4.1.1), ape(v.5.7-1), performance(v.0.10.8), cmdstanr(v.0.5.3), rstan(v.2.32.3), StanHeaders(v.2.26.28), brms(v.2.20.4), Rcpp(v.1.0.11), ggpmisc(v.0.5.5), ggpp(v.0.5.6), ggnewscale(v.0.4.9), cowplot(v.1.1.1), RColorBrewer(v.1.1-3), colorspace(v.2.1-0), lubridate(v.1.9.3), forcats(v.1.0.0), stringr(v.1.5.0), dplyr(v.1.1.3), purrr(v.1.0.2), readr(v.2.1.4), tidyr(v.1.3.0), tibble(v.3.2.1), ggplot2(v.3.4.4), tidyverse(v.2.0.0), Matrix(v.1.5-4.1), pander(v.0.6.5) and knitr(v.1.45)

loaded via a namespace (and not attached): pacman(v.0.5.1), utf8(v.1.2.4), tidyselect(v.1.2.0), htmlwidgets(v.1.6.2), grid(v.4.2.2), combinat(v.0.0-8), munsell(v.0.5.0), units(v.0.8-4), codetools(v.0.2-19), DT(v.0.30), miniUI(v.0.1.1.1), withr(v.2.5.2), Brobdingnag(v.1.2-9), highr(v.0.10), rstudioapi(v.0.15.0), stats4(v.4.2.2), bayesplot(v.1.10.0), labeling(v.0.4.3), emmeans(v.1.8.9), polyclip(v.1.10-6), mnormt(v.2.1.1), optimParallel(v.1.0-2), farver(v.2.1.1), bridgesampling(v.1.1-2), coda(v.0.19-4), vctrs(v.0.6.4), treeio(v.1.20.1), generics(v.0.1.3), TH.data(v.1.1-2), clusterGeneration(v.1.3.8), xfun(v.0.41), timechange(v.0.2.0), R6(v.2.5.1), markdown(v.1.11), doParallel(v.1.0.17), cachem(v.1.0.8), gridGraphics(v.0.5-1), promises(v.1.2.1), scales(v.1.2.1), multcomp(v.1.4-25), gtable(v.0.3.4), lwgeom(v.0.2-13), processx(v.3.8.2), phangorn(v.2.11.1), sandwich(v.3.1-0), rlang(v.1.1.2), MatrixModels(v.0.5-1), scatterplot3d(v.0.3-44), splines(v.4.2.2), confintr(v.1.0.2), rgdal(v.1.6-7), lazyeval(v.0.2.2), dichromat(v.2.0-0.1), checkmate(v.2.3.0), inline(v.0.3.19), yaml(v.2.3.7), reshape2(v.1.4.4), abind(v.1.4-5), threejs(v.0.3.3), crosstalk(v.1.2.0), backports(v.1.4.1), httpuv(v.1.6.12), tensorA(v.0.36.2), tools(v.4.2.2), bookdown(v.0.36), ggplotify(v.0.1.2), ellipsis(v.0.3.2), jquerylib(v.0.1.4), posterior(v.1.5.0), proxy(v.0.4-27), ggridges(v.0.5.4), polynom(v.1.4-1), plyr(v.1.8.9), base64enc(v.0.1-3), classInt(v.0.4-10), ps(v.1.7.5), prettyunits(v.1.2.0), viridis(v.0.6.4), zoo(v.1.8-12), leafem(v.0.2.3), fs(v.1.6.3), magrittr(v.2.0.3), data.table(v.1.14.8), SparseM(v.1.81), colourpicker(v.1.3.0), mvtnorm(v.1.2-3), matrixStats(v.1.0.0), hms(v.1.1.3), patchwork(v.1.1.3), shinyjs(v.2.1.0), mime(v.0.12), evaluate(v.0.23), xtable(v.1.8-4), XML(v.3.99-0.15), leaflet(v.2.2.0), shinystan(v.2.6.0), gridExtra(v.2.3), rstantools(v.2.3.1.1), compiler(v.4.2.2), KernSmooth(v.2.23-22), V8(v.4.4.0), crayon(v.1.5.2), htmltools(v.0.5.7), ggfun(v.0.1.3), later(v.1.3.1), tzdb(v.0.4.0), aplot(v.0.2.2), expm(v.0.999-7), RcppParallel(v.5.1.7), DBI(v.1.1.3), tweenr(v.2.0.2), formatR(v.1.14), MASS(v.7.3-60), cli(v.3.6.1), quadprog(v.1.5-8), parallel(v.4.2.2), insight(v.0.19.6), igraph(v.1.5.1), pkgconfig(v.2.0.3), numDeriv(v.2016.8-1.1), terra(v.1.7-55), foreach(v.1.5.2), dygraphs(v.1.1.1.6), QuickJSR(v.1.0.7), bslib(v.0.5.1), estimability(v.1.4.1), yulab.utils(v.0.1.0), distributional(v.0.3.2), callr(v.3.7.3), digest(v.0.6.33), rmarkdown(v.2.25), fastmatch(v.1.1-4), leafsync(v.0.1.0), tidytree(v.0.4.5), curl(v.5.1.0), shiny(v.1.7.5.1), gtools(v.3.9.4), quantreg(v.5.97), lifecycle(v.1.0.3), nlme(v.3.1-163), jsonlite(v.1.8.7), viridisLite(v.0.4.2), fansi(v.1.0.5), pillar(v.1.9.0), lattice(v.0.22-5), loo(v.2.6.0), fastmap(v.1.1.1), plotrix(v.3.8-3), pkgbuild(v.1.4.2), survival(v.3.5-7), glue(v.1.6.2), xts(v.0.13.1), bayestestR(v.0.13.1), png(v.0.1-8), shinythemes(v.1.2.0), iterators(v.1.0.14), ggforce(v.0.4.1), class(v.7.3-22), stringi(v.1.7.12), sass(v.0.4.7), stars(v.0.6-4), memoise(v.2.0.1) and e1071(v.1.7-13)


  1. Hawkesbury Institute for the Environment, Western Sydney University, NSW 2753, Australia, ↩︎

LS0tCnRpdGxlOiAiR2xvYmFsIGV4cG9zdXJlIHJpc2sgb2YgZnJvZ3MgdG8gaW5jcmVhc2luZyBlbnZpcm9ubWVudGFsIGRyeW5lc3MiCnN1YnRpdGxlOiAiU3VwcGxlbWVudGFyeSBJbmZvcm1hdGlvbiIKZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJWQvJW0vJVknKWAiCmF1dGhvcjoKICAtIE5pY2hvbGFzIEMuIFd1XltIYXdrZXNidXJ5IEluc3RpdHV0ZSBmb3IgdGhlIEVudmlyb25tZW50LCBXZXN0ZXJuIFN5ZG5leSBVbml2ZXJzaXR5LCBOU1cgMjc1MywgQXVzdHJhbGlhLCBuaWNob2xhcy53dS5uekBnbWFpbC5jb21dCm91dHB1dDoKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICBoaWdobGlnaHQ6IHRhbmdvCmVkaXRvcl9vcHRpb25zOgogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCmNzbDogLi9iaWIvdGhlLWpvdXJuYWwtb2YtZXhwZXJpbWVudGFsLWJpb2xvZ3kuY3NsCmJpYmxpb2dyYXBoeTogLi9iaWIvZHJvdWdodF9yZWYuYmliCmxpbmstY2l0YXRpb25zOiB0cnVlCi0tLQoKKipSRUFETUUqKiAgClRoaXMgZG9jdW1lbnQgY29udGFpbnMgdGhlICpSKiB3b3JrZmxvdyBmb3IgcHJvY2Vzc2luZyBhbmQgYW5hbHlzaW5nIHRoZSByYXcgZGF0YSwgYW5kIGdlbmVyYXRpbmcgZmlndXJlcyBmb3IgdGhlIG1hbnVzY3JpcHQgdGl0bGVkICIqKkdsb2JhbCBleHBvc3VyZSByaXNrIG9mIGZyb2dzIHRvIGluY3JlYXNpbmcgZW52aXJvbm1lbnRhbCBkcnluZXNzKioiLiAKCltHaXRIdWIgUmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL25pY2hvbGFzd3Vuei9nbG9iYWwtZnJvZy1kcm91Z2h0KQpUaGUgUm1hcmtkb3duIGZpbGUgY2FuIGJlIGRvd25sb2FkZWQgZnJvbSB0aGUgKkNvZGUqIGRyb3AgZG93biBtZW51ICh0b3AgcmlnaHQpLgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgY2FjaGUgPSBGQUxTRSwgdGlkeSA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQpvcHRpb25zKGRwbHlyLndpZHRoID0gSW5mLCBrbml0ci5rYWJsZS5OQSA9ICIiLCBkaWdpdHMgPSAyKQoKIyBMb2FkIGxpYnJhcnkKcGFjbWFuOjpwX2xvYWQocGFuZGVyLCBNYXRyaXgsIHRpZHl2ZXJzZSwgY29sb3JzcGFjZSwgUkNvbG9yQnJld2VyLCBjb3dwbG90LCBnZ25ld3NjYWxlLCBnZ3BtaXNjLAogICAgICAgICAgICAgICBicm1zLCByc3RhbiwgY21kc3RhbnIsIHBlcmZvcm1hbmNlLCBhcGUsIHBoeXRvb2xzLCBnZ3RyZWUsIE5pY2hlTWFwUiwKICAgICAgICAgICAgICAgbmNkZjQsIHJhc3Rlciwgc2YsIHRtYXAsIHRtYXB0b29scywgcmFzdGVyU3ApCgojIEZ1bmN0aW9ucwpteXRoZW1lIDwtIGZ1bmN0aW9uKCkgewogIHRoZW1lX2J3KCkgKwogICAgdGhlbWUocGFuZWwuYm9yZGVyICAgICAgICAgID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yICAgICAgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yICAgICAgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBheGlzLmxpbmUgICAgICAgICAgICAgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICBheGlzLnRpY2tzICAgICAgICAgICAgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgICBheGlzLnRleHQgICAgICAgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICAgIGF4aXMudGl0bGUgICAgICAgICAgICA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgICAgYXhpcy50aXRsZS55ICAgICAgICAgID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMyksCiAgICAgICAgICBheGlzLnRpdGxlLnggICAgICAgICAgPSBlbGVtZW50X3RleHQodmp1c3QgPSAtMSksCiAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kICAgICAgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSwKICAgICAgICAgIHBsb3QuYmFja2dyb3VuZCAgICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpLAogICAgICAgICAgcGxvdC5tYXJnaW4gICAgICAgICAgID0gdW5pdChjKDAuMiwgMC4yLCAwLjIsIDAuMiksIHVuaXRzID0gLCAiY20iKSwKICAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpLAogICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSBOQSksCiAgICAgICAgICBzdHJpcC50ZXh0LnggICAgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCAgICAgID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSBOQSksCiAgICAgICAgICBwbG90LnRpdGxlICAgICAgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKQogICAgKQp9ICMgc2V0IHVwIHBsb3QgdGhlbWUKCmFkZGJyYWNrZXQgPC0gZnVuY3Rpb24oeCl7cGFzdGUoIlsiLCB4LCAiXSIpfSAjIGFkZCBicmFja2V0cyBiZXR3ZWVuIHdvcmRzCgojIFNldCBvcHRpb25zIGluIFJzdGFuCnNldC5zZWVkKDEwKQpyc3Rhbl9vcHRpb25zKGF1dG9fd3JpdGUgPSBUUlVFKSAjIHRyYW5zbGF0ZSB0byBTVEFOIHBsYXRmb3JtIGZvciBydW5uaW5nIEJheWVzaWFuIG1vZGVsCm9wdGlvbnMobWMuY29yZXMgPSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSkgIyBkZXRlY3RzIGhvdyBtYW55IGNvcmVzIGF2YWlsYWJsZSB0byB1c2UKCiMgU2V0IGRpcmVjdG9yeQpzZXR3ZCgnL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0LycpIAoKIyBTZXQgZmlsZSBwYXRocwpkYXRhX3BhdGggICAgIDwtIGZpbGUucGF0aCgiZGF0YSIpCnNwYXRpYWxfcGF0aCAgPC0gZmlsZS5wYXRoKCJTcGF0aWFsIGRhdGEiKQpyYXN0ZXJTcF9wYXRoIDwtICJyYXN0ZXJTcC9TcGVjaWVzRGF0YS8iCmBgYAoKKipBYmJyZXZpYXRpb25zKioKCi0gQUk6IEFyaWRpdHkgSW5kZXgKLSAkZV9hJDogYWN0dWFsIHZhcG91ciBwcmVzc3VyZQotICRlX3MkOiBzYXR1cmF0aW9uIHZhcG91ciBwcmVzc3VyZQotIEVXTDogRXZhcG9yYXRpdmUgd2F0ZXIgbG9zcwotIElVQ046IEludGVybmF0aW9uYWwgVW5pb24gZm9yIENvbnNlcnZhdGlvbiBvZiBOYXR1cmUKLSBQRFNJOiBQYWxtZXIgRHJvdWdodCBTZXZlcml0eSBJbmRleAotIFBSSVNNQTogUHJlZmVycmVkIFJlcG9ydGluZyBJdGVtcyBmb3IgU3lzdGVtYXRpYyBSZXZpZXdzIGFuZCBNZXRhLUFuYWx5c2VzCi0gUkg6IFJlbGF0aXZlIGh1bWlkaXR5Ci0gJHJfaSQ6IFJlbGF0aXZlIHNraW4gcmVzaXN0YW5jZSBvciByZXNpc3RhbmNlIHRvIHdhdGVyIGxvc3MKLSBTQTogc3VyZmFjZS1hcmVhCi0gU1BQOiBTaGFyZWQgU29jaW9lY29ub21pYyBQYXRod2F5Ci0gVlBEOiBWYXBvdXIgcHJlc3N1cmUgZGVmaWNpdAotIFdvUzogV2ViIG9mIFNjaWVuY2UKLSBXVTogd2F0ZXIgdXB0YWtlCgoqKioKCiMgU3BhdGlhbCByaXNrIHstfQoKIyMgRGVzY3JpcHRvcnMgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0KClRoZSBmb2xsb3dpbmcgc2VyaWVzIG9mIGNvZGUgaXMgdG8gZXN0aW1hdGUgdGhlIHJpc2sgb2YgYW51cmFuIGFtcGhpYmlhbnMgdG8gaW5jcmVhc2luZyBhcmlkaXR5IChBcmlkaXR5IEluZGV4OyBBSSkgYW5kIGV4dHJlbWUgZHJvdWdodCAoUGFsbWVyIERyb3VnaHQgU2V2ZXJpdHkgSW5kZXg7IFBEU0kpLiBUaGUgQUkgd2FzIGNhdGVnb3Jpc2VkIHRvIGZpdmUgY2F0ZWdvcmllcyAoSHVtaWQsIERyeSBzdWItaHVtaWQsIFNlbWktYXJpZCwgQXJpZCwgYW5kIEh5cGVyLWFyaWQpIGFuZCB0aGUgUERTSSB3YXMgY2F0ZWdvcmlzZWQgdG8gc2V2ZW4gY2F0ZWdvcmllcyAoRXh0cmVtZWx5IG1vaXN0LCBWZXJ5IG1vaXN0LCBNb2RlcmF0ZSBtb2lzdCwgTm9ybWFsLCBNb2RlcmF0ZSBkcm91Z2h0LCBTZXZlcmUgZHJvdWdodCwgRXh0cmVtZSBkcm91Z2h0KSBiYXNlZCBvbiBkZXNjcmlwdGlvbnMgZnJvbSBAQnVkeWtvMTk2MSBhbmQgQFBhbG1lcjE5NjUsIHJlc3BlY3RpdmVseSAoKipUYWJsZSBTMSoqKS4KCkdlbmVyYWxpc2VkIGVjb2xvZ2ljYWwgdHlwZXMgb3Ig4oCYZWNvdHlwZeKAmSBvZiBlYWNoIGFudXJhbiBzcGVjaWVzIHdlcmUgY2xhc3NpZmllZCBiYXNlZCBvbiBkZXNjcmlwdGlvbnMgZnJvbSBATW9lbjIwMTcgZm9jdXNpbmcgb24gYWR1bHQgYmVoYXZpb3VyIGFuZCBtaWNyb2hhYml0YXQgcHJlZmVyZW5jZXMgb3V0c2lkZSB0aGUgYnJlZWRpbmcgc2Vhc29uLCBnaXZlbiB0aGF0IG1hbnkgYW51cmFucyBicmVlZCBpbiB3YXRlciBidXQgYXJlIG5vdCBhZGFwdGVkIHRvIGxpdmUgaW4gd2F0ZXIgYWxsIHllYXIgKCoqVGFibGUgUzIqKikuCgojIyMgVGFibGUgUzEgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgoqKlRhYmxlIFMxKiogQXJpZGl0eSBpbmRleCBbQEJ1ZHlrbzE5NjFdIGFuZCB0aGUgUGFsbWVyIERyb3VnaHQgU2V2ZXJpdHkgSW5kZXggW0BQYWxtZXIxOTY1XSBjYXRlZ29yaXNlZC4KCmBgYHtyIHRhYmxlIFMxLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpkYXRhLmZyYW1lKEFJID0gYygiSHVtaWQiLCAiRHJ5IHN1Yi1odW1pZCIsICJTZW1pLWFyaWQiLCAiQXJpZCIsIkh5cGVyLWFyaWQiLCAiIiwgIiIpLCAKICAgICAgICAgICBWYWx1ZSA9IGMoIuKJpSAwLjY1IiwgIjAuNTAg4oCTIOKJpCAwLjY1IiwgIjAuMjAg4oCTIOKJpCAwLjUwIiwgIjAuMDUg4oCTIOKJpCAwLjIwIiwgIjwgMC4wNSIsICIiLCAiIiksCiAgICAgICAgICAgUERTSSA9IGMoIkV4dHJlbWVseSBtb2lzdCIsICJWZXJ5IG1vaXN0IiwgIk1vZGVyYXRlIG1vaXN0IiwgIk5vcm1hbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1vZGVyYXRlIGRyb3VnaHQiLCAiU2V2ZXJlIGRyb3VnaHQiLCAiIEV4dHJlbWUgZHJvdWdodCIpLAogICAgICAgICAgIFZhbHVlID0gYygi4omlIDQiLCAiMyDigJMg4omkIDQiLCAiMiDigJMg4omkIDMiLCAiLTIg4oCTIOKJpCAyIiwgIi0zIOKAkyDiiaQgLTIiLCAiLTQg4oCTIOKJpCAtMyIsICI8IC00IikpICU+JQogIGRwbHlyOjpyZW5hbWUoIkFyaWRpdHkgaW5kZXggKEFJKSIgICAgICAgICAgICAgICAgICAgPSBBSSwKICAgICAgICAgICAgICAgICJBSSB2YWx1ZSIgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gVmFsdWUsCiAgICAgICAgICAgICAgICAiUGFsbWVyIERyb3VnaHQgU2V2ZXJpdHkgSW5kZXggKFBEU0kpIiA9IFBEU0ksCiAgICAgICAgICAgICAgICAiUERTSSBWYWx1ZSIgICAgICAgICAgICAgICAgICAgICAgICAgICA9IFZhbHVlLjEpICU+JQogIGtuaXRyOjprYWJsZSgpIApgYGAKCiMjIyBUYWJsZSBTMiB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzIqKiBNaWNyb2hhYml0YXQgcHJlZmVyZW5jZSBvciBlY290eXBlIFtATW9lbjIwMTddLgoKYGBge3IgdGFibGUgUzIsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmRhdGEuZnJhbWUoRWNvdHlwZSA9IGMoIkFxdWF0aWMiLCAiQXJib3JlYWwiLCAiU2VtaS1hcXVhdGljICIsICJHcm91bmQtZHdlbGxpbmciLCJGb3Nzb3JpYWwiLCAiU3RyZWFtLWR3ZWxsaW5nIiksIAogICAgICAgICAgIERlc2NyaXB0aW9uID0gYygiQWxtb3N0IGFsd2F5cyBpbiB3YXRlci4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFiaWxpdHkgdG8gY2xpbWIgdmVnZXRhdGlvbiBhbmQgc3BlbmRzIGEgc3Vic3RhbnRpYWwgYW1vdW50IG9mIHRpbWUgYWJvdmUgZ3JvdW5kIChlLmcuIGZvcmVzdHMsIG9uIHRvcCBvZiB2ZWdldGF0aW9ucyBpbiB3ZXRsYW5kcykuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGF5IG5lYXIgd2F0ZXIgYm9kaWVzLCB1c3VhbGx5IHBlcm1hbmVudCB3YXRlciAoZS5nLiBncm91bmQtbGV2ZWwgd2V0bGFuZHMpLiBPZnRlbiBvYnNlcnZlZCBpbiB3YXRlciBhbmQgbmVhcmJ5IHZlZ2V0YXRpb24uIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJUZXJyZXN0cmlhbCBvbmx5LCBub3QgYWx3YXlzIG5lYXIgd2F0ZXIgYm9kaWVzLCBob3dldmVyIGFsd2F5cyBpbiBhIG1vaXN0IGVudmlyb25tZW50IChlLmcuIGZvcmVzdCBsZWFmIGxpdHRlciwgbW9pc3Qgc29pbHMsIHNjcnVibGFuZHMsIGdyYXNzbGFuZCkuIFNvbWV0aW1lcyBhYm92ZSBncm91bmQgYW5kIHNvbWV0aW1lcyBzZW1pLWZvc3NvcmlhbC4gQ2FuIGJlIGNsYXNzaWZpZWQgYXMgYnJvYWQuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgbm9uLWJyZWVkaW5nIHNlYXNvbiBpcyBzcGVudCB1bmRlcmdyb3VuZCBpbiBidXJyb3dzLiBDYXBhYmxlIG9mIGJ1cnJvd2luZyBhbmQgYWVzdGl2YXRpbmcuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZXN0cmljdGVkIHRvIG5lYXIgZmFzdC1mbG93aW5nIHN0cmVhbXMgdXN1YWxseSBvbiByb2NrcyBvciB2ZWdldGF0aW9uIG5lYXIgc3RyZWFtcy4iKSkgJT4lCiAga25pdHI6OmthYmxlKCkgCmBgYAoKIyMgU3BlY2llcyByaWNobmVzcyB7LX0KCkFudXJhbiAoZnJvZ3MgYW5kIHRvYWRzKSAgZGlzdHJpYnV0aW9uIHNoYXBlIGZpbGVzIHdlcmUgb2J0YWluZWQgZnJvbSB0aGUgSW50ZXJuYXRpb25hbCBVbmlvbiBmb3IgQ29uc2VydmF0aW9uIG9mIE5hdHVyZSdzIFJlZCBMaXN0IG9mIFRocmVhdGVuZWQgU3BlY2llcyAoW0lVQ04gUmVkIExpc3RdKGh0dHBzOi8vd3d3Lml1Y25yZWRsaXN0Lm9yZy9yZXNvdXJjZXMvc3BhdGlhbC1kYXRhLWRvd25sb2FkKTsgZXh0cmFjdGVkIG9uIDExLzAxLzIwMjEpLiBTcGVjaWVzIHJpY2huZXNzIG9yIHNwZWNpZXMgYXNzZW1ibGFnZXMgd2FzIGRlZmluZWQgYXMgdGhlIHN1bSBvZiBzcGVjaWVzIGluIGVhY2ggZ3JpZCBjZWxsICgwLjXCsCksIGJhc2VkIG9uIHRoZSBnZW9ncmFwaGljIHJhbmdlLCBhbmQgd2FzIGNhbGN1bGF0ZWQgdXNpbmcgdGhlIGByYXN0ZXJpemVJVUNOYCBhbmQgYGNhbGNTUmAgZnVuY3Rpb24gZnJvbSB0aGUgZnJvbSB0aGUgW3Jhc3RlclNwXShodHRwczovL2dpdGh1Yi5jb20vUlMtZWNvL3Jhc3RlclNwKSBwYWNrYWdlLiBFY290eXBlLXNwZWNpZmljIHNwZWNpZXMgcmljaG5lc3Mgd2FzIGFsc28gY2FsY3VsYXRlZC4KCmBgYHtyIHNwLCBtZXNzYWdlPUZBTFNFLCBjYWNoZT1UUlVFLCByZXN1bHRzPSJoaWRlIn0KZmlsZWRpciA8LSAicmFzdGVyU3AvIgoKIyBDbGVhbiByYXcgZGF0YQpmcm9nX2RhdCA8LSByZWFkLmNzdihmaWxlLnBhdGgoZGF0YV9wYXRoLCAiYW51cmFuX3NwZWNpZXNfbGlzdC5jc3YiKSkgJT4lCiAgZHBseXI6OnNlbGVjdChnZW51czpzdHJhdGVneSwgU1ZMX2NtOmJpbm9taWFsX3RyZWVfcGh5bG8pICU+JQogIGRwbHlyOjptdXRhdGUobG5TVkwgICAgICAgPSBsb2coU1ZMX2NtKSwKICAgICAgICAgICAgICAgIGxuTWFzcyAgICAgID0gbG9nKG1hc3NfZyksCiAgICAgICAgICAgICAgICBsbkFyZWEgICAgICA9IGxvZyhzaGFwZV9hcmVhKSwKICAgICAgICAgICAgICAgIElVQ04gICAgICAgID0gZmFjdG9yKElVQ04sIGxldmVscyA9IGMoIkxlYXN0IENvbmNlcm4iLCAiTmVhciBUaHJlYXRlbmVkIiwgIlZ1bG5lcmFibGUiLCAiRW5kYW5nZXJlZCIsICJDcml0aWNhbGx5IEVuZGFuZ2VyZWQiLCAiRXh0aW5jdCIpKSwKICAgICAgICAgICAgICAgIG9yZGVyX25hbWUgID0gZmFjdG9yKG9yZGVyX25hbWUpLAogICAgICAgICAgICAgICAgZmFtaWx5X25hbWUgPSBmYWN0b3IoZmFtaWx5X25hbWUpLAogICAgICAgICAgICAgICAgZWNvdHlwZSAgICAgPSBmYWN0b3IoZWNvdHlwZSkpICU+JQogIGRwbHlyOjpmaWx0ZXIob3JkZXJfbmFtZSA9PSAiQU5VUkEiICYgZWNvdHlwZSAhPSAiIiAmIElVQ04gIT0gIiIgJiBJVUNOICE9ICJFeHRpbmN0IikgJT4lCiAgZHJvcGxldmVscygpCgojIENvbnZlcnQgc2hhcGUgZmlsZXMgaW50byByYXN0ZXJzIGFuZCBzYXZlIHRvIGZpbGUgb25jZSAoZG93bmxvYWRlZCBzaGFwZSBmaWxlcyAwOC8wMS8yMDIwKQojIG9ubHkgZXh0cmFjdGVkIGRpc3RyaWJ1dGlvbiBvZiBuYXRpdmUgcmFuZ2UKI2FudXJhbl9yYXN0IDwtIHJhc3Rlcml6ZUlVQ04oZHNuID0gcGFzdGUwKGZpbGVkaXIsICJBTlVSQS9BTlVSQS5zaHAiKSwgcmVzb2x1dGlvbiA9IDAuNSwgc2Vhc29uYWwgPSBjKDEsIDIpLCBvcmlnaW4gPSAxLCBwcmVzZW5jZSA9IGMoMSwyKSwgc2F2ZSA9IFRSVUUsIHBhdGggPSBwYXN0ZTAocmFzdGVyU3BfcGF0aCkpCgojIENhbGN1bGF0ZSBhbnVyYW4gcmljaG5lc3MgYW5kIGJ5IGVjb3R5cGUgCiMgVGhlIGNhbGNTUiBmdW5jdGlvbiB1c2VzIGEgc3RlcHdpc2UgcHJvY2VkdXJlIHRvIGNhbGN1bGF0ZSB0aGUgc3VtIG9mIHNwZWNpZXMgZm9yIGVhY2ggZ3JpZCBjZWxsLgphbnVyYW5fc3IgICAgPC0gcmFzdGVyU3A6OmNhbGNTUihzcGVjaWVzX25hbWVzID0gZnJvZ19kYXQkYmlub21pYWxfSVVDTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXN0ZTAocmFzdGVyU3BfcGF0aCkpCmFxdWF0aWNfc3IgICA8LSByYXN0ZXJTcDo6Y2FsY1NSKHNwZWNpZXNfbmFtZXMgPSBmcm9nX2RhdFtmcm9nX2RhdCRlY290eXBlID09ICJBcXVhdGljIiwgImJpbm9taWFsX0lVQ04iXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXN0ZTAocmFzdGVyU3BfcGF0aCkpCmFyYm9yZWFsX3NyICA8LSByYXN0ZXJTcDo6Y2FsY1NSKHNwZWNpZXNfbmFtZXMgPSBmcm9nX2RhdFtmcm9nX2RhdCRlY290eXBlID09ICJBcmJvcmVhbCIsICJiaW5vbWlhbF9JVUNOIl0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGFzdGUwKHJhc3RlclNwX3BhdGgpKQpmb3Nzb3JpYWxfc3IgPC0gcmFzdGVyU3A6OmNhbGNTUihzcGVjaWVzX25hbWVzID0gZnJvZ19kYXRbZnJvZ19kYXQkZWNvdHlwZSA9PSAiRm9zc29yaWFsIiwgImJpbm9taWFsX0lVQ04iXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhc3RlMChyYXN0ZXJTcF9wYXRoKSkKZ3JvdW5kX3NyICAgIDwtIHJhc3RlclNwOjpjYWxjU1Ioc3BlY2llc19uYW1lcyA9IGZyb2dfZGF0W2Zyb2dfZGF0JGVjb3R5cGUgPT0gIkdyb3VuZC1kd2VsbGluZyIsICJiaW5vbWlhbF9JVUNOIl0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGFzdGUwKHJhc3RlclNwX3BhdGgpKQpzZW1pX2FxX3NyICAgPC0gcmFzdGVyU3A6OmNhbGNTUihzcGVjaWVzX25hbWVzID0gZnJvZ19kYXRbZnJvZ19kYXQkZWNvdHlwZSA9PSAiU2VtaS1hcXVhdGljIiwgImJpbm9taWFsX0lVQ04iXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXN0ZTAocmFzdGVyU3BfcGF0aCkpCnN0cmVhbV9zciAgICA8LSByYXN0ZXJTcDo6Y2FsY1NSKHNwZWNpZXNfbmFtZXMgPSBmcm9nX2RhdFtmcm9nX2RhdCRlY290eXBlID09ICJTdHJlYW0tZHdlbGxpbmciLCAiYmlub21pYWxfSVVDTiJdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhc3RlMChyYXN0ZXJTcF9wYXRoKSkKCiMgQ29udmVydCByYXN0ZXIgdG8gbWF0cml4IHRoZW4gdG8gZGF0YSBmcmFtZQphbnVyYW5fc3JfZGYgICAgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoYW51cmFuX3NyKSkgJT4lIGRwbHlyOjpyZW5hbWUoc3BlY2llc19uID0gbGF5ZXIpCmFxdWF0aWNfc3JfZGYgICA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhhcXVhdGljX3NyKSkgJT4lIGRwbHlyOjpyZW5hbWUoYXF1YXRpY19uID0gbGF5ZXIpCmFyYm9yZWFsX3NyX2RmICA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhhcmJvcmVhbF9zcikpICU+JSBkcGx5cjo6cmVuYW1lKGFyYm9yZWFsX24gPSBsYXllcikKZm9zc29yaWFsX3NyX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKGZvc3NvcmlhbF9zcikpICU+JSBkcGx5cjo6cmVuYW1lKGZvc3NvcmlhbF9uID0gbGF5ZXIpCmdyb3VuZF9zcl9kZiAgICA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhncm91bmRfc3IpKSAlPiUgZHBseXI6OnJlbmFtZShncm91bmRfbiA9IGxheWVyKQpzZW1pX2FxX3NyX2RmICAgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoc2VtaV9hcV9zcikpICU+JSBkcGx5cjo6cmVuYW1lKHNlbWlfYXFfbiA9IGxheWVyKQpzdHJlYW1fc3JfZGYgICAgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoc3RyZWFtX3NyKSkgJT4lIGRwbHlyOjpyZW5hbWUoc3RyZWFtX24gPSBsYXllcikKYGBgCgpUaGVyZSB3ZXJlIGByIGxlbmd0aCh1bmlxdWUoZnJvZ19kYXQkYmlub21pYWxfSVVDTikpYCBhbnVyYW4gc3BlY2llcyBmcm9tIHRoZSBJVUNOIFJlZCBMaXN0IGF2YWlsYWJsZSBmb3IgdGhlIEFJIGFuZCBQRFNJIGFuYWx5c2lzLgoKIyMgQ2FsY3VsYXRlIEFJIGFuZCBQRFNJIHstfQoKSGlnaCByZXNvbHV0aW9uICh+NCBrbV4yXikgZ2xvYmFsIGRhdGFzZXQgb24gcHJlY2lwaXRhdGlvbiAobW0vbW9udGgpIGFuZCBwb3RlbnRpYWwgZXZhcG90cmFuc3BpcmF0aW9uIChtbS9tb250aCkgd2VyZSBvYnRhaW5lZCBmcm9tIEFiYXR6b2dsb3UgZXQgYWwuICgyMDE4KSB1bmRlciAxKSB0aGUgY3VycmVudCBjbGltYXRlICgxOTcw4oCTMjAwMCksIDIpIGFuIGludGVybWVkaWF0ZSBncmVlbmhvdXNlIGdhcyBlbWlzc2lvbiBzY2VuYXJpbyBvZiArMsKwQyAoU2hhcmVkIFNvY2lvZWNvbm9taWMgUGF0aHdheSAy4oCTNC41OyBTUFAy4oCTNC41KSwgYW5kIDMpIGEgaGlnaCBncmVlbmhvdXNlIGdhcyBlbWlzc2lvbiBvciDigJxidXNpbmVzcy1hcy11c3VhbOKAnSBzY2VuYXJpbyBvZiArNMKwQyAoU1NQNeKAkzguNSkgYnkgMjA4MOKAkzIwOTkgKCoqRmlnLiBTMWHigJNmKiopLiAKCldlIG9idGFpbmVkIGEgc2VsZi1jYWxpYnJhdGVkIFBEU0kgd2l0aCBQZW5tYW7igJNNb250ZWl0aCBwb3RlbnRpYWwgZXZhcG90cmFuc3BpcmF0aW9uIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBjbGltYXRlICgxOTcw4oCTMjAwMCkgYW5kIGFuIGludGVybWVkaWF0ZSBhbmQgaGlnaCBlbWlzc2lvbiBzY2VuYXJpbyBieSAyMDgw4oCTMjA5OSAoU1NQMuKAkzQuNSBhbmQgU1NQNS04LjUpIGZyb20gWmhhbyBhbmQgRGFpICgyMDIyKS4gVGhlIFNTUDLigJM0LjUgYW5kIFNTUDXigJM4LjUgc2NlbmFyaW9zIHdlcmUgYmFzZWQgb24gdGhlIGF2ZXJhZ2Ugb2YgMjUgQ01JUDYgbW9kZWxzIG9mIHByZWNpcGl0YXRpb24sIGV2YXBvdHJhbnNwaXJhdGlvbiwgc29pbCBtb2lzdHVyZSwgYW5kIHJ1bm9mZiAoRXlyaW5nIGV0IGFsLiwgMjAxNiksIHdoZXJlIHRoZSBtZWFuIGFubnVhbCBzdXJmYWNlIHRlbXBlcmF0dXJlIGlzIGV4cGVjdGVkIHRvIGluY3JlYXNlIGJ5IDIuN8KwQyAoMi4x4oCTMy41wrBDIHJhbmdlKSBhbmQgNC40wrBDICgzLjPigJM1LjfCsEMgcmFuZ2UpLCByZXNwZWN0aXZlbHkgYnkgMjA4MOKAkzIxMDAgKElQQ0MsIDIwMjEpLgoKYGBge3IgY2xpbSBkYXQsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPVRSVUUsIHJlc3VsdHM9ImhpZGUifQojIEltcG9ydCB0aGUgZG93bmxvYWRlZCBmaWxlcwpwcHRfcmFzdCA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayh4ID0gZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ1RlcnJhQ2xpbWF0ZTE5ODEyMDEwX3BwdC5uYycpKSwgYW51cmFuX3NyKSAjIFByZWNpcGl0YXRpb24geWVhciAxOTgxLTIwMTAgLSBQciAobW0pCnBldF9yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlMTk4MTIwMTBfcGV0Lm5jJykpLCBhbnVyYW5fc3IpICMgRXZhcG90cmFuc3BpcmF0aW9uIDE5ODEtMjAxMCAtIEVUMCAobW0pCgojICsyQyBhbmQgKzRDIGZ1dHVyZSBzY2VuYXJpb3MgCnBwdF8yQ19yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlMkNfcHB0Lm5jJykpLCBhbnVyYW5fc3IpCnBldF8yQ19yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlMkNfcGV0Lm5jJykpLCBhbnVyYW5fc3IpCnBwdF80Q19yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlNENfcHB0Lm5jJykpLCBhbnVyYW5fc3IpCnBldF80Q19yYXN0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlNENfcGV0Lm5jJykpLCBhbnVyYW5fc3IpCgojIE9idGFpbiBtZWFuIHZhbHVlcyBmcm9tIDE5ODEtMjAxMApwcHRfbWVhbl9yYXN0ICAgIDwtIHJhc3Rlcjo6Y2FsYyhwcHRfcmFzdCwgZnVuID0gbWVhbiwgbmEucm0gPSBUUlVFKQpwZXRfbWVhbl9yYXN0ICAgIDwtIHJhc3Rlcjo6Y2FsYyhwZXRfcmFzdCwgZnVuID0gbWVhbiwgbmEucm0gPSBUUlVFKSAKcHB0XzJDX21lYW5fcmFzdCA8LSByYXN0ZXI6OmNhbGMocHB0XzJDX3Jhc3QsIGZ1biA9IG1lYW4sIG5hLnJtID0gVFJVRSkgCnBldF8yQ19tZWFuX3Jhc3QgPC0gcmFzdGVyOjpjYWxjKHBldF8yQ19yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpCnBwdF80Q19tZWFuX3Jhc3QgPC0gcmFzdGVyOjpjYWxjKHBwdF80Q19yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpCnBldF80Q19tZWFuX3Jhc3QgPC0gcmFzdGVyOjpjYWxjKHBldF80Q19yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpIAoKIyBPYnRhaW4gbWVhbiB2YWx1ZXMgZnJvbSAxMC15ZWFyIG1vbnRobHkgUERTSQpQRFNJX3NzcDI0NV9yYXN0IDwtIHJhc3Rlcjo6c3RhY2soeCA9IGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICAncGRzaXNjLm1vbnRobHkuMTkwMC0yMTAwLnIyLjV4Mi41LkVuc0F2ZzI1TW9kZWxzLlRQMi5pcGUtMi5zc3AyNDUubmMnKSkKUERTSV9zc3A1ODVfcmFzdCA8LSByYXN0ZXI6OnN0YWNrKHggPSBmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAgJ3Bkc2lzYy5tb250aGx5LjE5MDAtMjEwMC5yMi41eDIuNS5FbnNBdmcyNU1vZGVscy5UUDIuaXBlLTIuc3NwNTg1Lm5jJykpCgpQRFNJX2N1cl9yYXN0IDwtIHJhc3Rlcjo6c3Vic2V0KFBEU0lfc3NwMjQ1X3Jhc3QsIGdyZXAoIlgxOTcuKnxYMTk4Lip8WDE5OS4qIiwgbmFtZXMoUERTSV9zc3AyNDVfcmFzdCksIHZhbHVlID0gVCkpClBEU0lfMkNfcmFzdCAgPC0gcmFzdGVyOjpzdWJzZXQoUERTSV9zc3AyNDVfcmFzdCwgZ3JlcCgiWDIwNy4qfFgyMDguKnxYMjA5LioiLCBuYW1lcyhQRFNJX3NzcDI0NV9yYXN0KSwgdmFsdWUgPSBUKSkKUERTSV80Q19yYXN0ICA8LSByYXN0ZXI6OnN1YnNldChQRFNJX3NzcDU4NV9yYXN0LCBncmVwKCJYMjA3Lip8WDIwOC4qfFgyMDkuKiIsIG5hbWVzKFBEU0lfc3NwNTg1X3Jhc3QpLCB2YWx1ZSA9IFQpKQoKUERTSV9jdXJfbWVhbl9yYXN0IDwtIHJhc3Rlcjo6Y2FsYyhQRFNJX2N1cl9yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpClBEU0lfMkNfbWVhbl9yYXN0ICA8LSByYXN0ZXI6OmNhbGMoUERTSV8yQ19yYXN0LCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpIApQRFNJXzRDX21lYW5fcmFzdCAgPC0gcmFzdGVyOjpjYWxjKFBEU0lfNENfcmFzdCwgZnVuID0gbWVhbiwgbmEucm0gPSBUUlVFKSAKCiMgQ2FsY3VsYXRlIGFyaWRpdHkgaW5kZXggW1ByZWNpcGl0YXRpb24gKHBwdCkgLyBFdmFwb3RyYW5zcGlyYXRpb24gKHBldCldCmFpX3Jhc3QgICAgPC0gcmFzdGVyOjpvdmVybGF5KHggPSBwcHRfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHBldF9tZWFuX3Jhc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuKHggLyB5KX0pCmFpXzJDX3Jhc3QgPC0gcmFzdGVyOjpvdmVybGF5KHggPSBwcHRfMkNfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHBldF8yQ19tZWFuX3Jhc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuKHggLyB5KX0pIAphaV80Q19yYXN0IDwtIHJhc3Rlcjo6b3ZlcmxheSh4ID0gcHB0XzRDX21lYW5fcmFzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBwZXRfNENfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuID0gZnVuY3Rpb24oeCwgeSkge3JldHVybih4IC8geSl9KSAKCiMgQ2FsY3VsYXRlIGNoYW5nZSBpbiBQRFNJCiMgUmVwcm9qZWN0IGludGVuc2l0eSByYXN0ZXIgdG8gbWF0Y2ggYW51cmFuX3NyClBEU0lfY3VyX21lYW5fcmFzdCA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIoUERTSV9jdXJfbWVhbl9yYXN0LCBhbnVyYW5fc3IpClBEU0lfMkNfbWVhbl9yYXN0ICA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIoUERTSV8yQ19tZWFuX3Jhc3QsIGFudXJhbl9zcikKUERTSV80Q19tZWFuX3Jhc3QgIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihQRFNJXzRDX21lYW5fcmFzdCwgYW51cmFuX3NyKQoKUERTSV8yQ19kaWZmX3Jhc3QgPC0gcmFzdGVyOjpvdmVybGF5KHggPSBQRFNJX2N1cl9tZWFuX3Jhc3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IFBEU0lfMkNfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1biA9IGZ1bmN0aW9uKHgsIHkpIHtyZXR1cm4oeSAtIHgpfSkgClBEU0lfNENfZGlmZl9yYXN0IDwtIHJhc3Rlcjo6b3ZlcmxheSh4ID0gUERTSV9jdXJfbWVhbl9yYXN0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBQRFNJXzRDX21lYW5fcmFzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuKHkgLSB4KX0pIAoKIyBDb252ZXJ0IHJhc3RlciB0byBtYXRyaXggdGhlbiB0byBkYXRhIGZyYW1lCmFpX2RmICAgIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKGFpX3Jhc3QpKQphaV8yQ19kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhhaV8yQ19yYXN0KSkKYWlfNENfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoYWlfNENfcmFzdCkpCgpQRFNJXzJDX2RpZmZfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV8yQ19kaWZmX3Jhc3QpKQpQRFNJXzRDX2RpZmZfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV80Q19kaWZmX3Jhc3QpKQoKIyBDb252ZXJ0IGFyaWRpdHkgaW5kZXggaW50byBjYXRlZ29yeQphaV9kZiA8LSBhaV9kZiAlPiUgCiAgIyBSZWNvZGUKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gY2FzZV93aGVuKAogICAgaXMuaW5maW5pdGUobGF5ZXIpIH4gJ0h1bWlkJywKICAgIGxheWVyID49IDAuNjUgfiAnSHVtaWQnLCAgICAgICAgICAgICAKICAgIGxheWVyID49IDAuNSAmIGxheWVyIDwgMC42NSB+ICdEcnkgc3ViLWh1bWlkJywKICAgIGxheWVyID49IDAuMiAmIGxheWVyIDwgMC41IH4gJ1NlbWktYXJpZCcsIAogICAgbGF5ZXIgPj0gMC4wNSAmIGxheWVyIDwgMC4yIH4gJ0FyaWQnLCAKICAgIGxheWVyIDwgMC4wNSB+ICdIeXBlci1hcmlkJwogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gZmFjdG9yKGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCdIeXBlci1hcmlkJywgJ0FyaWQnLCAnU2VtaS1hcmlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgphaV8yQ19kZiA8LSBhaV8yQ19kZiAlPiUgCiAgIyBSZWNvZGUKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gY2FzZV93aGVuKAogICAgaXMuaW5maW5pdGUobGF5ZXIpIH4gJ0h1bWlkJywKICAgIGxheWVyID49IDAuNjUgfiAnSHVtaWQnLCAgICAgICAgICAgICAgICAgICAgICAgCiAgICBsYXllciA+PSAwLjUgJiBsYXllciA8IDAuNjUgfiAnRHJ5IHN1Yi1odW1pZCcsIAogICAgbGF5ZXIgPj0gMC4yICYgbGF5ZXIgPCAwLjUgfiAnU2VtaS1hcmlkJywgICAgICAKICAgIGxheWVyID49IDAuMDUgJiBsYXllciA8IDAuMiB+ICdBcmlkJywgICAKICAgIGxheWVyIDwgMC4wNSB+ICdIeXBlci1hcmlkJwogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gZmFjdG9yKGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCdIeXBlci1hcmlkJywgJ0FyaWQnLCAnU2VtaS1hcmlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgphaV80Q19kZiA8LSBhaV80Q19kZiAlPiUgCiAgIyBSZWNvZGUKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gY2FzZV93aGVuKAogICAgaXMuaW5maW5pdGUobGF5ZXIpIH4gJ0h1bWlkJywKICAgIGxheWVyID49IDAuNjUgfiAnSHVtaWQnLCAgICAgICAgICAgICAgICAgICAgICAgCiAgICBsYXllciA+PSAwLjUgJiBsYXllciA8IDAuNjUgfiAnRHJ5IHN1Yi1odW1pZCcsIAogICAgbGF5ZXIgPj0gMC4yICYgbGF5ZXIgPCAwLjUgfiAnU2VtaS1hcmlkJywgICAgICAKICAgIGxheWVyID49IDAuMDUgJiBsYXllciA8IDAuMiB+ICdBcmlkJywgICAKICAgIGxheWVyIDwgMC4wNSB+ICdIeXBlci1hcmlkJwogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gZmFjdG9yKGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCdIeXBlci1hcmlkJywgJ0FyaWQnLCAnU2VtaS1hcmlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgojIENvbnZlcnQgUERTSSB0byBjYXRlZ29yeQpQRFNJXzJDX2RpZmZfZGYgPC0gUERTSV8yQ19kaWZmX2RmICU+JSAKICAjIFJlY29kZQogIGRwbHlyOjptdXRhdGUoY2hhbmdlXzJDID0gY2FzZV93aGVuKAogICAgbGF5ZXIgPj0gNCB+ICI0IiwgICAgICAgICAgICAgICAgCiAgICBsYXllciA+PSAzICYgbGF5ZXIgPCA0IH4gJzMnLAogICAgbGF5ZXIgPj0gMiAmIGxheWVyIDwgMyB+ICcyJywgCiAgICBsYXllciA+PSAxICYgbGF5ZXIgPCAyIH4gJzEnLCAgCiAgICBsYXllciA+PSAtMSAmIGxheWVyIDwgMSB+ICcwJywgIAogICAgbGF5ZXIgPj0gLTIgJiBsYXllciA8IC0xIH4gJy0xJywgCiAgICBsYXllciA+PSAtMyAmIGxheWVyIDwgLTIgfiAnLTInLCAKICAgIGxheWVyID49IC00ICYgbGF5ZXIgPCAtMyB+ICctMycsIAogICAgbGF5ZXIgPCAtNCB+ICctNCcKICApKSAlPiUgCiAgIyBDb252ZXJ0IHRvIG9yZGVyZWQgZmFjdG9yCiAgZHBseXI6Om11dGF0ZShjaGFuZ2VfMkMgPSBmYWN0b3IoY2hhbmdlXzJDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJy00JywgJy0zJywgJy0yJywgJy0xJywgJzAnLCAnMScsICcyJywgJzMnLCAnNCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkKClBEU0lfNENfZGlmZl9kZiA8LSBQRFNJXzRDX2RpZmZfZGYgJT4lIAogICMgUmVjb2RlCiAgZHBseXI6Om11dGF0ZShjaGFuZ2VfNEMgPSBjYXNlX3doZW4oCiAgICBsYXllciA+PSA0IH4gIjQiLCAgICAgICAgICAgICAgICAKICAgIGxheWVyID49IDMgJiBsYXllciA8IDQgfiAnMycsCiAgICBsYXllciA+PSAyICYgbGF5ZXIgPCAzIH4gJzInLCAKICAgIGxheWVyID49IDEgJiBsYXllciA8IDIgfiAnMScsICAKICAgIGxheWVyID49IC0xICYgbGF5ZXIgPCAxIH4gJzAnLCAgCiAgICBsYXllciA+PSAtMiAmIGxheWVyIDwgLTEgfiAnLTEnLCAKICAgIGxheWVyID49IC0zICYgbGF5ZXIgPCAtMiB+ICctMicsIAogICAgbGF5ZXIgPj0gLTQgJiBsYXllciA8IC0zIH4gJy0zJywgCiAgICBsYXllciA8IC00IH4gJy00JwogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNoYW5nZV80QyA9IGZhY3RvcihjaGFuZ2VfNEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnLTQnLCAnLTMnLCAnLTInLCAnLTEnLCAnMCcsICcxJywgJzInLCAnMycsICc0JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQpgYGAKCmBgYHtyIEZpZyBTMSwgbWVzc2FnZT1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYuNSwgZmlnLndpZHRoPTl9CiMgQ3JvcCBhbmQgbWFzawp3b3JsZCAgICAgIDwtIHJnZGFsOjpyZWFkT0dSKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICJuZV81MG1fbGFuZC9uZV81MG1fbGFuZC5zaHAiKSkKd29ybGRfc3BkZiA8LSBzcDo6U3BhdGlhbFBvbHlnb25zRGF0YUZyYW1lKHdvcmxkLCB3b3JsZEBkYXRhKSAKCiMgUHJlY2lwaXRhdGlvbgpwcHRfY3Vycl9wbG90IDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKHBwdF9tZWFuX3Jhc3QpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGxheWVyKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfc2VxdWVudGlhbChwYWxldHRlID0gIllsR25CdSIsIGxpbSA9IGMoMCwgNjUwKSwgbmFtZSA9ICJQcmVjaXBpdGF0aW9uIChtbSkiKSArCiAgZ2d0aXRsZSgiQ3VycmVudCAoMTk4MS0yMDEwKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJ3aWR0aCA9IDEwLCBiYXJoZWlnaHQgPSAwLjMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLnBvc2l0aW9uID0gImJvdHRvbSIpKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAgCgpwcHRfMkNfcGxvdCA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhwcHRfMkNfbWVhbl9yYXN0KSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBsYXllcikpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJZbEduQnUiLCBsaW0gPSBjKDAsIDY1MCkpICsKICBnZ3RpdGxlKCIrMsKwQyAoMjA4MC0yMTAwKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpCgpwcHRfNENfcGxvdCA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhwcHRfNENfbWVhbl9yYXN0KSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBsYXllcikpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJZbEduQnUiLCBsaW0gPSBjKDAsIDY1MCkpICsKICBnZ3RpdGxlKCIrNMKwQyAoMjA4MC0yMTAwKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICAKCnBwdF9sZWdlbmQgPC0gY293cGxvdDo6Z2V0X2xlZ2VuZChwcHRfY3Vycl9wbG90KQoKcHB0X3Byb3cgPC0gY293cGxvdDo6cGxvdF9ncmlkKHBwdF9jdXJyX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIHBwdF8yQ19wbG90ICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgcHB0XzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGFsaWduID0gInYiLCBuY29sID0gMywgbGFiZWxzID0gYygnYScsICdiJywgJ2MnKSkgCgpwcHRfcGxvdHMgPC0gY293cGxvdDo6cGxvdF9ncmlkKHBwdF9wcm93LCBwcHRfbGVnZW5kLCBuY29sID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKCiMgRXZhcG90cmFuc3BpcmF0aW9uCnBldF9jdXJyX3Bsb3QgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMocGV0X21lYW5fcmFzdCkpICU+JQogIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gbGF5ZXIpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfY29udGludW91c19zZXF1ZW50aWFsKHBhbGV0dGUgPSAiUm9ja2V0IiwgbGltID0gYygwLCAzMDApLCBuYW1lID0gIkV2YXBvdHJhbnNwaXJhdGlvbiAobW0pIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcndpZHRoID0gMTAsIGJhcmhlaWdodCA9IDAuMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICAKCnBldF8yQ19wbG90IDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKHBldF8yQ19tZWFuX3Jhc3QpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGxheWVyKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfc2VxdWVudGlhbChwYWxldHRlID0gIlJvY2tldCIsIGxpbSA9IGMoMCwgMzAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkKCnBldF80Q19wbG90IDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKHBldF80Q19tZWFuX3Jhc3QpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGxheWVyKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2NvbnRpbnVvdXNfc2VxdWVudGlhbChwYWxldHRlID0gIlJvY2tldCIsIGxpbSA9IGMoMCwgMzAwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIAoKcGV0X2xlZ2VuZCA8LSBjb3dwbG90OjpnZXRfbGVnZW5kKHBldF9jdXJyX3Bsb3QpCgpwZXRfcHJvdyA8LSBjb3dwbG90OjpwbG90X2dyaWQocGV0X2N1cnJfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgcGV0XzJDX3Bsb3QgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBwZXRfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgYWxpZ24gPSAidiIsIG5jb2wgPSAzLCBsYWJlbHMgPSBjKCdkJywgJ2UnLCAnZicpKSAKCnBldF9wbG90cyA8LSBjb3dwbG90OjpwbG90X2dyaWQocGV0X3Byb3csIHBldF9sZWdlbmQsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMSwgLjEpKQoKIyBBcmlkaXR5IEluZGV4CmFyaWRfY29sIDwtIGMoJyM4RTA2M0InLCAnI0NCNkQ1MycsICcjRTk5QTJDJywgJyNGNUQ1NzknLCAnd2hpdGUnKQphaV9jdXJyX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBhaV9kZiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGNhdGVnb3J5KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBhcmlkX2NvbCwKICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJBcmlkaXR5IEluZGV4IikgKwogIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZV92b2lkKCkgKyAKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuMiwgJ2NtJyksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpCgphaV8yQ19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gYWlfMkNfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBjYXRlZ29yeSkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYXJpZF9jb2wsCiAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiQXJpZGl0eSBJbmRleCIpICsKICB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWVfdm9pZCgpICsgCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpCgphaV80Q19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gYWlfNENfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBjYXRlZ29yeSkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYXJpZF9jb2wsCiAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiQXJpZGl0eSBJbmRleCIpICsKICB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWVfdm9pZCgpICsgCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpCgphaV9sZWdlbmQgPC0gY293cGxvdDo6Z2V0X2xlZ2VuZChhaV9jdXJyX3Bsb3QpCgphaV9wcm93IDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChhaV9jdXJyX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGFpXzJDX3Bsb3QgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBhaV80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBhbGlnbiA9ICJ2IiwgbmNvbCA9IDMsIGxhYmVscyA9IGMoJ2cnLCAnaCcsICdpJykpIAoKYWlfcGxvdHMgPC0gY293cGxvdDo6cGxvdF9ncmlkKGFpX3Byb3csIGFpX2xlZ2VuZCwgbmNvbCA9IDEsIHJlbF9oZWlnaHRzID0gYygxLCAuMSkpCgpjb3dwbG90OjpwbG90X2dyaWQocHB0X3Bsb3RzLCBwZXRfcGxvdHMsIGFpX3Bsb3RzLCBuY29sID0gMSkKYGBgCgoqKkZpZy4gUzEuKiogQ2xpbWF0ZSBkYXRhIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBhcmlkaXR5IGluZGV4LiBNZWFuIHByZWNpcGl0YXRpb24gKG1tKSB1bmRlciAoKiphKiopIHRoZSBjdXJyZW50IHNjZW5hcmlvIGZyb20gMTk4MS0yMDEwLCAoKipiKiopIGFuIGludGVybWVkaWF0ZSBlbWlzc2lvbiBzY2VuYXJpbyAoU2hhcmVkIFNvY2lvZWNvbm9taWMgUGF0aHdheXMgMiAtIDQuNTsgU1NQMi00LjUpLCBhbmQgKCoqYyoqKSBhIGhpZ2ggZW1pc3Npb24gc2NlbmFyaW8gKFNTUDUtOC41KSBieSAyMDgwLTIxMDAuIE1lYW4gcG90ZW50aWFsIGV2YXBvdHJhbnNwaXJhdGlvbiAobW0pIHVuZGVyICgqKmQqKikgdGhlIGN1cnJlbnQgc2NlbmFyaW8gZnJvbSAxOTgxLTIwMTAsICgqKmUqKikgYW4gaW50ZXJtZWRpYXRlIGVtaXNzaW9uIHNjZW5hcmlvIChTU1AyLTQuNSksIGFuZCAoKipmKiopIGEgaGlnaCBlbWlzc2lvbiBzY2VuYXJpbyAoU1NQNS04LjUpIGJ5IDIwODAtMjEwMC4gQ2FsY3VsYXRlZCBBcmlkaXR5IEluZGV4IGZvciAoKipnKiopIHRoZSBjdXJyZW50IHNjZW5hcmlvIGZyb20gMTk4MS0yMDEwLCAoKipoKiopIGFuIGludGVybWVkaWF0ZSBlbWlzc2lvbiBzY2VuYXJpbyAoU1NQMi00LjUpLCBhbmQgKCoqaSoqKSBhIGhpZ2ggZW1pc3Npb24gc2NlbmFyaW8gKFNTUDUtOC41KSBieSAyMDgwLTIxMDAuIAoKIyMgQUkgcmlzayB7LX0KClRvIGV4YW1pbmUgdGhlIHJlbGF0aW9uc2hpcCBvZiBzcGVjaWVzIHJpY2huZXNzIHdpdGggYXJpZGl0eSwgdGhlIG51bWJlciBvZiBzcGVjaWVzIHBlciBnaXJkIGNlbGwgd2FzIG92ZXJsYXBwZWQgd2l0aCB0aGUgYXJpZGl0eSByYXN0ZXIgbGF5ZXIsIHdoZXJlIGVhY2ggZ3JpZCB3YXMgYXNzaWduZWQgYW4gQUkgY2F0ZWdvcnkuIFRoZSBjaGFuZ2UgaW4gc3BlY2llcyByaWNobmVzcyBiZXR3ZWVuIHRoZSBjdXJyZW50IGFuZCBwcm9qZWN0ZWQgKGVpdGhlciArMiBvciArNCDCsEMgd2FybWluZykgQUkgY2F0ZWdvcnkgd2FzIGNhbGN1bGF0ZWQgYXMgdGhlIGNoYW5nZSBpbiBBSSBjYXRlZ29yeSBncmlkcyAocmVzb2x1dGlvbiAwLjXCsCBmb3IgZGVjaW1hbCBkZWdyZWUgY29vcmRpbmF0ZXMpIG9jY3VwaWVkIGJ5IGFudXJhbnMgcmVsYXRpdmUgdG8gdGhlIGZ1dHVyZSBwcm9qZWN0aW9uLiBBIGRlY3JlYXNlIGluZGljYXRlcyByZWR1Y2VkIG51bWJlciBvZiBzcGVjaWVzIHdpdGggdGhlIGFzc2lnbmVkIEFJIGNhdGVnb3J5IGFuZCB2aWNlIHZlcnNhLgoKYGBge3IgQUl9CiMgTWVyZ2UgYXJpZGl0eSBpbmRleCwgKzRDIGFuZCBhbXBoaWJpYW4gc3BlY2llcyByaWNobmVzcwphaV9zcF9kZiA8LSBhaV9kZiAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhaV8yQ19kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lCiAgZHBseXI6OmZ1bGxfam9pbihhaV80Q19kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lCiAgZHBseXI6OmZ1bGxfam9pbihhbnVyYW5fc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFxdWF0aWNfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFyYm9yZWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihmb3Nzb3JpYWxfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGdyb3VuZF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc2VtaV9hcV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc3RyZWFtX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OnJlbmFtZShhcmlkaXR5ID0gbGF5ZXIueCwKICAgICAgICAgICAgICAgIGFyaWRpdHlfMkMgPSBsYXllci55LAogICAgICAgICAgICAgICAgYXJpZGl0eV80QyA9IGxheWVyLAogICAgICAgICAgICAgICAgY2F0ZWdvcnkgPSBjYXRlZ29yeS54LAogICAgICAgICAgICAgICAgY2F0ZWdvcnlfMkMgPSBjYXRlZ29yeS55LAogICAgICAgICAgICAgICAgY2F0ZWdvcnlfNEMgPSBjYXRlZ29yeSkgJT4lCiAgZHJvcF9uYShjYXRlZ29yeSkKCiMgQ2FsY3VsYXRlIGdyaWQgY2VsbHMgb2NjdXBpZWQgZm9yIGN1cnJlbnQgY2xpbWF0ZQphaV9zcF9zdW0gPC0gZGF0YS5mcmFtZShhaV9zcF9kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGNhdGVnb3J5KSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShzcGVjaWVzX24gICA9IGxlbmd0aChzcGVjaWVzX25bIWlzLm5hKHNwZWNpZXNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFxdWF0aWNfbiAgID0gbGVuZ3RoKGFxdWF0aWNfblshaXMubmEoYXF1YXRpY19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJib3JlYWxfbiAgPSBsZW5ndGgoYXJib3JlYWxfblshaXMubmEoYXJib3JlYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9uID0gbGVuZ3RoKGZvc3NvcmlhbF9uWyFpcy5uYShmb3Nzb3JpYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9uICAgID0gbGVuZ3RoKGdyb3VuZF9uWyFpcy5uYShncm91bmRfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbWlfYXFfbiAgID0gbGVuZ3RoKHNlbWlfYXFfblshaXMubmEoc2VtaV9hcV9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtX24gICAgPSBsZW5ndGgoc3RyZWFtX25bIWlzLm5hKHN0cmVhbV9uKV0pKSkgJT4lCiAgZHBseXI6Om11dGF0ZShzY2VuYXJpbyA9ICJDdXJyZW50IiwKICAgICAgICAgICAgICAgIGFsbF9mcmVxICAgICAgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2ZyZXEgICA9IGFxdWF0aWNfbiAvIHN1bShhcXVhdGljX24pICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfZnJlcSAgPSBhcmJvcmVhbF9uIC8gc3VtKGFyYm9yZWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZm9zc29yaWFsX2ZyZXEgPSBmb3Nzb3JpYWxfbiAvIHN1bShmb3Nzb3JpYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfZnJlcSAgICA9IGdyb3VuZF9uIC8gc3VtKGdyb3VuZF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfZnJlcSAgID0gc2VtaV9hcV9uIC8gc3VtKHNlbWlfYXFfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fZnJlcSAgICA9IHN0cmVhbV9uIC8gc3VtKHN0cmVhbV9uKSAqIDEwMCkKCiMgQ2FsY3VsYXRlIGdyaWQgY2VsbHMgb2NjdXBpZWQgZm9yIGZ1dHVyZSBjbGltYXRlCmFpXzJDX3NwX3N1bSA8LSBkYXRhLmZyYW1lKGFpX3NwX2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoY2F0ZWdvcnlfMkMpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiAgID0gbGVuZ3RoKHNwZWNpZXNfblshaXMubmEoc3BlY2llc19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXF1YXRpY19uICAgPSBsZW5ndGgoYXF1YXRpY19uWyFpcy5uYShhcXVhdGljX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmJvcmVhbF9uICA9IGxlbmd0aChhcmJvcmVhbF9uWyFpcy5uYShhcmJvcmVhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9zc29yaWFsX24gPSBsZW5ndGgoZm9zc29yaWFsX25bIWlzLm5hKGZvc3NvcmlhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdW5kX24gICAgPSBsZW5ndGgoZ3JvdW5kX25bIWlzLm5hKGdyb3VuZF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtaV9hcV9uICAgPSBsZW5ndGgoc2VtaV9hcV9uWyFpcy5uYShzZW1pX2FxX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1fbiAgICA9IGxlbmd0aChzdHJlYW1fblshaXMubmEoc3RyZWFtX24pXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKHNjZW5hcmlvID0gIlNTUDI0NSIsCiAgICAgICAgICAgICAgICBhbGxfZnJlcSAgICAgICA9IHNwZWNpZXNfbiAvIHN1bShzcGVjaWVzX24pICogMTAwLAogICAgICAgICAgICAgICAgYXF1YXRpY19mcmVxICAgPSBhcXVhdGljX24gLyBzdW0oYXF1YXRpY19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFyYm9yZWFsX2ZyZXEgID0gYXJib3JlYWxfbiAvIHN1bShhcmJvcmVhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9mcmVxID0gZm9zc29yaWFsX24gLyBzdW0oZm9zc29yaWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZ3JvdW5kX2ZyZXEgICAgPSBncm91bmRfbiAvIHN1bShncm91bmRfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzZW1pX2FxX2ZyZXEgICA9IHNlbWlfYXFfbiAvIHN1bShzZW1pX2FxX24pICogMTAwLAogICAgICAgICAgICAgICAgc3RyZWFtX2ZyZXEgICAgPSBzdHJlYW1fbiAvIHN1bShzdHJlYW1fbikgKiAxMDApICU+JSAKICBkcGx5cjo6cmVuYW1lKGNhdGVnb3J5ID0gY2F0ZWdvcnlfMkMpIAoKYWlfNENfc3Bfc3VtIDwtIGRhdGEuZnJhbWUoYWlfc3BfZGYgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShjYXRlZ29yeV80QykgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2Uoc3BlY2llc19uICAgPSBsZW5ndGgoc3BlY2llc19uWyFpcy5uYShzcGVjaWVzX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcXVhdGljX24gICA9IGxlbmd0aChhcXVhdGljX25bIWlzLm5hKGFxdWF0aWNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyYm9yZWFsX24gID0gbGVuZ3RoKGFyYm9yZWFsX25bIWlzLm5hKGFyYm9yZWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfbiA9IGxlbmd0aChmb3Nzb3JpYWxfblshaXMubmEoZm9zc29yaWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91bmRfbiAgICA9IGxlbmd0aChncm91bmRfblshaXMubmEoZ3JvdW5kX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW1pX2FxX24gICA9IGxlbmd0aChzZW1pX2FxX25bIWlzLm5hKHNlbWlfYXFfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbV9uICAgID0gbGVuZ3RoKHN0cmVhbV9uWyFpcy5uYShzdHJlYW1fbildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoc2NlbmFyaW8gPSAiU1NQNTg1IiwKICAgICAgICAgICAgICAgIGFsbF9mcmVxICAgICAgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2ZyZXEgICA9IGFxdWF0aWNfbiAvIHN1bShhcXVhdGljX24pICogMTAwLAogICAgICAgICAgICAgICAgcmJvcmVhbF9mcmVxICAgPSBhcmJvcmVhbF9uIC8gc3VtKGFyYm9yZWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZm9zc29yaWFsX2ZyZXEgPSBmb3Nzb3JpYWxfbiAvIHN1bShmb3Nzb3JpYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfZnJlcSAgICA9IGdyb3VuZF9uIC8gc3VtKGdyb3VuZF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfZnJlcSAgID0gc2VtaV9hcV9uIC8gc3VtKHNlbWlfYXFfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fZnJlcSAgICA9IHN0cmVhbV9uIC8gc3VtKHN0cmVhbV9uKSAqIDEwMCkgJT4lIAogIGRwbHlyOjpyZW5hbWUoY2F0ZWdvcnkgPSBjYXRlZ29yeV80QykKYGBgCgojIyBQRFNJIHJpc2sgey19CgpXaXRoIGEgbW9udGhseSBwcmVkaWN0aW9uIG9mIFBEU0kgZnJvbSAxOTUwIHRvIDIxMDAgZ2xvYmFsbHkgYXZhaWxhYmxlIGZyb20gWmhhbyBhbmQgRGFpICgyMDIyKSwgd2UgY2F0ZWdvcmlzZWQgZnV0dXJlIGRyb3VnaHQgcmlzayBpbiB0aHJlZSB3YXlzOiAxKSBhbiBpbmNyZWFzZSBpbiBkcm91Z2h0IGludGVuc2l0eSAoZGVjcmVhc2UgaW4gUERTSSksIGFuIGluY3JlYXNlIGluIGRyb3VnaHQgZnJlcXVlbmN5IChtb250aGx5IFBEU0kgY291bnRzIGJlbG93IC0yIHBlciB5ZWFyKSwgYW5kIGFuIGluY3JlYXNlIGluIGRyb3VnaHQgZHVyYXRpb24gKG51bWJlciBvZiBjb25zZWN1dGl2ZSBtb250aHMgd2l0aCBQRFNJIHZhbHVlcyBiZWxvdyAtMikuIENoYW5nZSBpbiBkcm91Z2h0IGludGVuc2l0eSAozpRQRFNJfltpbnRlbnNpdHldfiksIGZyZXF1ZW5jeSAozpRQRFNJfltmcmVxdWVuY3ldfiksICBhbmQgZHVyYXRpb24gKM6UUERTSX5bZHVyYXRpb25dfikgdW5kZXIgYSArMiBvciArNCDCsEMgd2FybWluZyBzY2VuYXJpbyAoMjA4MOKAkzIxMDApIHdhcyBjYWxjdWxhdGVkIHJlbGF0aXZlIHRvIHRoZSAxOTcw4oCTMjAwMCBtb250aGx5IGNsaW1hdG9sb2d5IHBlciBnaXJkIGNlbGwgKM6UUERTSSA9IFBEU0l+W2Z1dHVyZV1+IOKAkyBQRFNJfltjdXJyZW50XX4pLiBOb3RlLCB0aGUgdGVtcG9yYWwgcmVzb2x1dGlvbiB3YXMgbGltaXRlZCB0byBtb250aGx5IHZhcmlhdGlvbiBhcyB0aGUgUERTSSB3YXMgZGV2ZWxvcGVkIHRvIG1vbml0b3IgbG9uZy10ZXJtIG1ldGVvcm9sb2dpY2FsIGRyb3VnaHQuCgpgYGB7ciBQRFNJIGludH0KIyBDaGFuZ2UgaW4gUERTSSBpbnRlbnNpdHkgClBEU0lfc3BfZGYgPC0gYW51cmFuX3NyX2RmICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKFBEU0lfMkNfZGlmZl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oUERTSV80Q19kaWZmX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhcXVhdGljX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhcmJvcmVhbF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZm9zc29yaWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihncm91bmRfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKHNlbWlfYXFfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKHN0cmVhbV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpyZW5hbWUoUERTSV8yQyA9IGxheWVyLngsCiAgICAgICAgICAgICAgICBQRFNJXzRDID0gbGF5ZXIueSkgJT4lCiAgZHJvcF9uYShjaGFuZ2VfMkMpICU+JQogIGZpbHRlcihzcGVjaWVzX24gIT0gIk5BIikKCiMgQ2FsY3VsYXRlIGdyaWQgY2VsbHMgb2NjdXBpZWQgZm9yIGN1cnJlbnQgY2xpbWF0ZQpQRFNJX3NwXzJDIDwtIGRhdGEuZnJhbWUoUERTSV9zcF9kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShjaGFuZ2VfMkMpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShzcGVjaWVzX24gICA9IGxlbmd0aChzcGVjaWVzX25bIWlzLm5hKHNwZWNpZXNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcXVhdGljX24gICA9IGxlbmd0aChhcXVhdGljX25bIWlzLm5hKGFxdWF0aWNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmJvcmVhbF9uICA9IGxlbmd0aChhcmJvcmVhbF9uWyFpcy5uYShhcmJvcmVhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9uID0gbGVuZ3RoKGZvc3NvcmlhbF9uWyFpcy5uYShmb3Nzb3JpYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91bmRfbiAgICA9IGxlbmd0aChncm91bmRfblshaXMubmEoZ3JvdW5kX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtaV9hcV9uICAgPSBsZW5ndGgoc2VtaV9hcV9uWyFpcy5uYShzZW1pX2FxX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtX24gICAgPSBsZW5ndGgoc3RyZWFtX25bIWlzLm5hKHN0cmVhbV9uKV0pKSkgJT4lCiAgZHBseXI6Om11dGF0ZShhbGxfZnJlcSAgICAgICA9IHNwZWNpZXNfbiAvIHN1bShzcGVjaWVzX24pICogMTAwLAogICAgICAgICAgICAgICAgYXF1YXRpY19mcmVxICAgPSBhcXVhdGljX24gLyBzdW0oYXF1YXRpY19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFyYm9yZWFsX2ZyZXEgID0gYXJib3JlYWxfbiAvIHN1bShhcmJvcmVhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9mcmVxID0gZm9zc29yaWFsX24gLyBzdW0oZm9zc29yaWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZ3JvdW5kX2ZyZXEgICAgPSBncm91bmRfbiAvIHN1bShncm91bmRfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzZW1pX2FxX2ZyZXEgICA9IHNlbWlfYXFfbiAvIHN1bShzZW1pX2FxX24pICogMTAwLAogICAgICAgICAgICAgICAgc3RyZWFtX2ZyZXEgICAgPSBzdHJlYW1fbiAvIHN1bShzdHJlYW1fbikgKiAxMDApCgpQRFNJX3NwXzRDIDwtIGRhdGEuZnJhbWUoUERTSV9zcF9kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShjaGFuZ2VfNEMpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShzcGVjaWVzX24gICA9IGxlbmd0aChzcGVjaWVzX25bIWlzLm5hKHNwZWNpZXNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcXVhdGljX24gICA9IGxlbmd0aChhcXVhdGljX25bIWlzLm5hKGFxdWF0aWNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmJvcmVhbF9uICA9IGxlbmd0aChhcmJvcmVhbF9uWyFpcy5uYShhcmJvcmVhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9uID0gbGVuZ3RoKGZvc3NvcmlhbF9uWyFpcy5uYShmb3Nzb3JpYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91bmRfbiAgICA9IGxlbmd0aChncm91bmRfblshaXMubmEoZ3JvdW5kX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtaV9hcV9uICAgPSBsZW5ndGgoc2VtaV9hcV9uWyFpcy5uYShzZW1pX2FxX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtX24gICAgPSBsZW5ndGgoc3RyZWFtX25bIWlzLm5hKHN0cmVhbV9uKV0pKSkgJT4lCiAgZHBseXI6Om11dGF0ZShhbGxfZnJlcSAgICAgICA9IHNwZWNpZXNfbiAvIHN1bShzcGVjaWVzX24pICogMTAwLAogICAgICAgICAgICAgICAgYXF1YXRpY19mcmVxICAgPSBhcXVhdGljX24gLyBzdW0oYXF1YXRpY19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFyYm9yZWFsX2ZyZXEgID0gYXJib3JlYWxfbiAvIHN1bShhcmJvcmVhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9mcmVxID0gZm9zc29yaWFsX24gLyBzdW0oZm9zc29yaWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZ3JvdW5kX2ZyZXEgICAgPSBncm91bmRfbiAvIHN1bShncm91bmRfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzZW1pX2FxX2ZyZXEgICA9IHNlbWlfYXFfbiAvIHN1bShzZW1pX2FxX24pICogMTAwLAogICAgICAgICAgICAgICAgc3RyZWFtX2ZyZXEgICAgPSBzdHJlYW1fbiAvIHN1bShzdHJlYW1fbikgKiAxMDApCmBgYAoKYGBge3IgUERTSSBmcmVxfQojIENhbGN1bGF0ZSBmcmVxdWVuY3kgb2YgbW9kZXJhdGUgdG8gZXh0cmVtZSBkcm91Z2h0ICg8LTIgUERTSSkgcGVyIHllYXIuCgojIFRlbXBvcmFsIGNoYW5nZSBpbiBQRFNJIGludGVuc2l0eQpQRFNJXzJDX3RpbWVfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV9zc3AyNDVfcmFzdCkpClBEU0lfNENfdGltZV9kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhQRFNJX3NzcDU4NV9yYXN0KSkKCiMgQ29udmVydCB3aWRlIHRvIGxvbmcKZnJlcV8yQ19kZiA8LSBQRFNJXzJDX3RpbWVfZGYgJT4lCiAgdGlkeXI6OnBpdm90X2xvbmdlcighYygieCIsInkiKSwgbmFtZXNfdG8gPSAiZGF0ZXMiLCB2YWx1ZXNfdG8gPSAiUERTSSIpICU+JQogIGRhdGEuZnJhbWUoKSAlPiUKICB0aWR5cjo6c2VwYXJhdGUoZGF0ZXMsIGMoInllYXIiLCAnbW9udGhzJykpICU+JQogIGRwbHlyOjptdXRhdGUoeWVhciA9IGFzLm51bWVyaWMoc3Vic3RyaW5nKHllYXIsIDIpKSkgJT4lCiAgZHBseXI6OmZpbHRlcih5ZWFyID49IDE5NTAgJiB5ZWFyICE9IDIxMDApCgpmcmVxXzRDX2RmIDwtIFBEU0lfNENfdGltZV9kZiAlPiUKICB0aWR5cjo6cGl2b3RfbG9uZ2VyKCFjKCJ4IiwieSIpLCBuYW1lc190byA9ICJkYXRlcyIsIHZhbHVlc190byA9ICJQRFNJIikgJT4lCiAgZGF0YS5mcmFtZSgpICU+JQogIHRpZHlyOjpzZXBhcmF0ZShkYXRlcywgYygieWVhciIsICdtb250aHMnKSkgJT4lCiAgZHBseXI6Om11dGF0ZSh5ZWFyID0gYXMubnVtZXJpYyhzdWJzdHJpbmcoeWVhciwgMikpKSAlPiUKICBkcGx5cjo6ZmlsdGVyKHllYXIgPj0gMTk1MCAmIHllYXIgIT0gMjEwMCkKCiMgU3VtbWFyaXNlIGF2ZXJhZ2UgbW9udGhseSBjb3VudHMgPC0yIFBEU0kgZnJvbSAxOTcwIHRvIDE5OTkgb3IgMjA4MCB0byAyMTAwCmZyZXFfbWVhbl9kZiA8LSBmcmVxXzJDX2RmICU+JQogIGRwbHlyOjpmaWx0ZXIoeWVhciA+PSAxOTcwICYgeWVhciA8PSAxOTk5KSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoeCwgeSwgeWVhcikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShjb3VudCA9IHN1bShQRFNJIDwgLTIpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoeCwgeSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShtZWFuX2N1cnIgPSBtZWFuKGNvdW50KSkKICAKZnJlcV8yQ19kaWZmX2RmIDwtIGZyZXFfMkNfZGYgJT4lCiAgZHBseXI6OmZpbHRlcih5ZWFyID49IDIwODAgJiB5ZWFyICE9IDIxMDApICU+JQogIGRwbHlyOjpncm91cF9ieSh4LCB5LCB5ZWFyKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGNvdW50ID0gc3VtKFBEU0kgPCAtMikpICU+JSAKICBkcGx5cjo6Z3JvdXBfYnkoeCwgeSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShtZWFuXzJDID0gbWVhbihjb3VudCkpICU+JSAKICBkcGx5cjo6aW5uZXJfam9pbihmcmVxX21lYW5fZGYsIGJ5ID0gYygieCIgPSAieCIsICJ5IiA9ICJ5IikpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl8yQyA9IG1lYW5fMkMgLSBtZWFuX2N1cnIpCgpmcmVxXzRDX2RpZmZfZGYgPC0gZnJlcV80Q19kZiAlPiUKICBkcGx5cjo6ZmlsdGVyKHllYXIgPj0gMjA4MCAmIHllYXIgIT0gMjEwMCkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KHgsIHksIHllYXIpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoY291bnQgPSBzdW0oUERTSSA8IC0yKSkgJT4lIAogIGRwbHlyOjpncm91cF9ieSh4LCB5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKG1lYW5fNEMgPSBtZWFuKGNvdW50KSkgJT4lIAogIGRwbHlyOjppbm5lcl9qb2luKGZyZXFfMkNfZGlmZl9kZiwgYnkgPSBjKCJ4IiA9ICJ4IiwgInkiID0gInkiKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkaWZmXzRDID0gbWVhbl80QyAtIG1lYW5fY3VycikKYGBgCgpgYGB7ciBQRFNJIGR1cn0KIyBDYWxjdWxhdGUgZHVyYXRpb24gb2YgbW9kZXJhdGUgdG8gZXh0cmVtZSBkcm91Z2h0ICg8LTIgUERTSSkgZnJvbSAxOTcwIHRvIDE5OTkKZHVyX2N1cnJfZGYgPC0gZnJlcV8yQ19kZiAlPiUKICBkcGx5cjo6bXV0YXRlKGJpbiA9IGlmZWxzZShQRFNJIDwgLTIsIDEsIDApKSAlPiUKICBkcGx5cjo6ZmlsdGVyKHllYXIgPj0gMTk3MCAmIHllYXIgPD0gMTk5OSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KHgsIHkpICU+JSAKICBkcGx5cjo6c3VtbWFyaXNlKG1lYW5fY3VyciA9IG1lYW4ocmxlKGJpbikkbGVuZ3Roc1tybGUoYmluKSR2YWx1ZXM9PTFdKSkgJT4lCiAgcmVwbGFjZShpcy5uYSguKSwgMCkKCiMgQ2FsY3VsYXRlIGR1cmF0aW9uIG9mIG1vZGVyYXRlIHRvIGV4dHJlbWUgZHJvdWdodCAoPC0yIFBEU0kpIGZyb20gMjA4MCB0byAyMTAwCmR1cl8yQ19kZiA8LSBmcmVxXzJDX2RmICU+JQogIGRwbHlyOjptdXRhdGUoYmluID0gaWZlbHNlKFBEU0kgPCAtMiwgMSwgMCkpICU+JSAKICBkcGx5cjo6ZmlsdGVyKHllYXIgPj0gMjA4MCAmIHllYXIgIT0gMjEwMCkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KHgsIHkpICU+JSAKICBkcGx5cjo6c3VtbWFyaXNlKG1lYW5fMkMgPSBtZWFuKHJsZShiaW4pJGxlbmd0aHNbcmxlKGJpbikkdmFsdWVzPT0xXSkpICU+JQogIHJlcGxhY2UoaXMubmEoLiksIDApICU+JQogIGRwbHlyOjppbm5lcl9qb2luKGR1cl9jdXJyX2RmLCBieSA9IGMoIngiID0gIngiLCAieSIgPSAieSIpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRpZmZfMkMgPSBtZWFuXzJDIC0gbWVhbl9jdXJyKQoKZHVyXzRDX2RmIDwtIGZyZXFfNENfZGYgJT4lIAogIGRwbHlyOjptdXRhdGUoYmluID0gaWZlbHNlKFBEU0kgPCAtMiwgMSwgMCkpICU+JQogIGRwbHlyOjpncm91cF9ieSh4LCB5KSAlPiUgCiAgZHBseXI6OmZpbHRlcih5ZWFyID49IDIwODAgJiB5ZWFyICE9IDIxMDApICU+JQogIGRwbHlyOjpzdW1tYXJpc2UobWVhbl80QyA9IG1lYW4ocmxlKGJpbikkbGVuZ3Roc1tybGUoYmluKSR2YWx1ZXM9PTFdKSkgJT4lCiAgcmVwbGFjZShpcy5uYSguKSwgMCkgJT4lCiAgZHBseXI6OmlubmVyX2pvaW4oZHVyXzJDX2RmLCBieSA9IGMoIngiID0gIngiLCAieSIgPSAieSIpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRpZmZfNEMgPSBtZWFuXzRDIC0gbWVhbl9jdXJyKQpgYGAKClRoZSBzaW11bHRhbmVvdXMgcmlzayBvZiBkcm91Z2h0IGludGVuc2l0eSwgZnJlcXVlbmN5LCBhbmQgZHVyYXRpb24gd2l0aGluIGEgZ3JpZCBjZWxsIHRoYXQgYXJlIG9jY3VwaWVkIGJ5IGFudXJhbnMgd2FzIGNhbGN1bGF0ZWQgYnkgY29udmVydGluZyBlYWNoIHJpc2sgY2F0ZWdvcnkgYXMgYmluYXJ5LiBHaXJkIGNlbGxzIHdpdGggYSDOlFBEU0l+W2ludGVuc2l0eV1+IGJlbG93IC0xIChpbmRpY2F0aW5nIGEgZGVjcmVhc2UgaW4gUERTSSkgd2VyZSBhc3NpZ25lZCBhIOKAmDHigJkgYmluYXJ5LiBCb3RoIM6UUERTSX5bZnJlcXVlbmN5XX4gYW5kIM6UUERTSX5bZHVyYXRpb25dfiB3ZXJlIGFzc2lnbmVkIGEgYmluYXJ5IG9mIOKAmDHigJkgaWYgdGhlIGdyaWQgY2VsbCBoYXMgYSB2YWx1ZSBvZiAxIG1vbnRoIG9yIGhpZ2hlciAoaW5kaWNhdGluZyBpbmNyZWFzZSBpbiBmcmVxdWVuY3kgb3IgZHVyYXRpb24gcmVsYXRpdmUgdG8gY3VycmVudCBzY2VuYXJpbykuICkuIFRoZSBudW1iZXIgb2Ygb3ZlcmxhcHBpbmcgYmluYXJpZXMgd2VyZSBzdW1tZWQgdXAgcGVyIGdyaWQgY2VsbC4gVGhlcmVmb3JlLCBhIHJpc2sgZmFjdG9yIG9mIDIgaW5kaWNhdGUgc3BlY2llcyBhc3NlbWJsYWdlcyBpbiB0aGUgZ3JpZCBjZWxsIGFyZSBhdCBpbmNyZWFzaW5nIHJpc2sgb2YgdHdvIGRyb3VnaHQgZXZlbnRzLiBXZSBlc3RpbWF0ZWQgd2hpY2ggc3BlY2llcyBhc3NlbWJsYWdlcyB3ZXJlIGF0IHJpc2sgb2YgZXhwZXJpZW5jaW5nIGRyb3VnaHQgZXZlbnRzIHVzaW5nIGFuIGFyYml0cmFyeSByaXNrIGZhY3RvciBzY2FsZSAoc3BlY2llcyByaWNobmVzcyDDlyBkcm91Z2h0IHJpc2spLCB3aGVyZSBncmlkIGNlbGxzIHdpdGggaGlnaCBkcm91Z2h0IHJpc2sgYW5kIGhpZ2ggc3BlY2llcyByaWNobmVzcyBoYXZlIGhpZ2hlciDigJxhc3NlbWJsYWdlLWxldmVsIHJpc2vigJ0gdGhhbiBncmlkIGNlbGxzIHdpdGggaGlnaCBkcm91Z2h0IHJpc2sgYW5kIGxvdyBzcGVjaWVzIHJpY2huZXNzIChsb3cgYXNzZW1ibGFnZS1sZXZlbCByaXNrKS4KCmBgYHtyIFBEU0kgY29tYn0KIyBJbnRlbnNpdHkKbmFtZXMoUERTSV8yQ19kaWZmX3Jhc3QpIDwtICJkZWx0YV9pbnRfMkMiCm5hbWVzKFBEU0lfNENfZGlmZl9yYXN0KSA8LSAiZGVsdGFfaW50XzRDIgoKIyBGcmVxdWVuY3kKZnJlcV9kaWZmX3Jhc3QgPC0gcmFzdGVyRnJvbVhZWihmcmVxXzRDX2RpZmZfZGYpICMgY29udmVydCB0byByYXN0ZXIKY3JzKGZyZXFfZGlmZl9yYXN0KSA8LSAiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQgK25vX2RlZnMgK2VsbHBzPVdHUzg0ICt0b3dnczg0PTAsMCwwIgpmcmVxX2RpZmZfcmFzdCA8LSBwcm9qZWN0UmFzdGVyKGZyZXFfZGlmZl9yYXN0LCBhbnVyYW5fc3IpICMgbWF0Y2ggYW51cmFuIGV4dGVudApmcmVxX2RpZmZfZGYgICA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhmcmVxX2RpZmZfcmFzdCkpCgpQRFNJX2ZyZXFfZGlmZiA8LSBzdWJzZXQoZnJlcV9kaWZmX3Jhc3QsIDQ6NSkKbmFtZXMoUERTSV9mcmVxX2RpZmYpIDwtIGMoImRlbHRhX2ZyZXFfMkMiLCAiZGVsdGFfZnJlcV80QyIpCgojIER1cmF0aW9uCmR1cl9kaWZmX3Jhc3QgPC0gcmFzdGVyOjpyYXN0ZXJGcm9tWFlaKGR1cl80Q19kZikgIyBjb252ZXJ0IHRvIHJhc3RlcgpjcnMoZHVyX2RpZmZfcmFzdCkgPC0gIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0ICtub19kZWZzICtlbGxwcz1XR1M4NCArdG93Z3M4ND0wLDAsMCIKZHVyX2RpZmZfcmFzdCA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIoZHVyX2RpZmZfcmFzdCwgYW51cmFuX3NyKSAjIG1hdGNoIGFudXJhbiBleHRlbnQKZHVyX2RpZmZfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoZHVyX2RpZmZfcmFzdCkpCgpQRFNJX2R1cl9kaWZmICA8LSBzdWJzZXQoZHVyX2RpZmZfcmFzdCwgNDo1KQpuYW1lcyhQRFNJX2R1cl9kaWZmKSA8LSBjKCJkZWx0YV9kdXJfMkMiLCAiZGVsdGFfZHVyXzRDIikKCiMgQ29tYmluZSByZWxhdGl2ZSBQRFNJIG1ldHJpY3MKUERTSV9yaXNrX2NvbWJfcmFzdCA8LSByYXN0ZXI6OnN0YWNrKFBEU0lfMkNfZGlmZl9yYXN0LCBQRFNJXzRDX2RpZmZfcmFzdCwgUERTSV9mcmVxX2RpZmYsIFBEU0lfZHVyX2RpZmYsIHJlc2FtcGxlKGFudXJhbl9zciwgUERTSV80Q19kaWZmX3Jhc3QpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIApQRFNJX3Jpc2tfY29tYl9kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhQRFNJX3Jpc2tfY29tYl9yYXN0KSkgJT4lCiAgZHBseXI6OnJlbmFtZSgic3BfbiIgPSBsYXllcikgJT4lCiAgZHBseXI6OmZpbHRlcighaXMubmEoc3BfbikpICU+JQogIGRwbHlyOjptdXRhdGUoZGVsdGFfaW50XzJDX2JpbiA9IGlmZWxzZShkZWx0YV9pbnRfMkMgPCAtMSwgMSwgMCksICMgZGVsdGFfUERTSSA8IC0xCiAgICAgICAgIGRlbHRhX2ludF80Q19iaW4gPSBpZmVsc2UoZGVsdGFfaW50XzRDIDwgLTEsIDEsIDApLCAjIGRlbHRhX1BEU0kgPCAtMQogICAgICAgICBkZWx0YV9mcmVxXzJDX2JpbiA9IGlmZWxzZShkZWx0YV9mcmVxXzJDID4xLCAxLCAwKSwgIyBtb250aCA+IDEKICAgICAgICAgZGVsdGFfZnJlcV80Q19iaW4gPSBpZmVsc2UoZGVsdGFfZnJlcV80QyA+MSwgMSwgMCksICMgbW9udGggPiAxCiAgICAgICAgIGRlbHRhX2R1cl8yQ19iaW4gPSBpZmVsc2UoZGVsdGFfZHVyXzJDID4xLCAxLCAwKSwgIyBtb250aCA+IDEKICAgICAgICAgZGVsdGFfZHVyXzRDX2JpbiA9IGlmZWxzZShkZWx0YV9kdXJfNEMgPjEsIDEsIDApKSAlPiUgIyBtb250aCA+IDEgCiAgZHBseXI6OnJvd3dpc2UoKSAlPiUKICBkcGx5cjo6bXV0YXRlKGNvdW50XzJDID0gc3VtKGRlbHRhX2ludF8yQ19iaW4sIGRlbHRhX2ZyZXFfMkNfYmluLCBkZWx0YV9kdXJfMkNfYmluLCBuYS5ybSA9IFQpLAogICAgICAgICAKICAgICAgICAgY291bnRfNEMgPSBzdW0oZGVsdGFfaW50XzRDX2JpbiwgZGVsdGFfZnJlcV80Q19iaW4sIGRlbHRhX2R1cl80Q19iaW4sIG5hLnJtID0gVCksCiAgICAgICAgIHJpc2tfMkMgID0gc3BfbiAqIGNvdW50XzJDLAogICAgICAgICByaXNrXzRDICA9IHNwX24gKiBjb3VudF80QywKICAgICAgICAgY291bnRfMkMgPSBmYWN0b3IoY291bnRfMkMsIGxldmVscyA9IGMoIjMiLCAiMiIsICIxIikpLAogICAgICAgICBjb3VudF80QyA9IGZhY3Rvcihjb3VudF80QywgbGV2ZWxzID0gYygiMyIsICIyIiwgIjEiKSkKICAgICAgICAgKQpgYGAKCmBgYHtyIEZpZyBTMiwgbWVzc2FnZT1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYuNSwgZmlnLndpZHRoPTl9CiMgQ29tYmluZSBhYnNvbHV0ZSBQRFNJIG1ldHJpY3MKUERTSV9hYl9yYXN0IDwtIHJhc3Rlcjo6c3RhY2soUERTSV9jdXJfbWVhbl9yYXN0LCBQRFNJXzJDX21lYW5fcmFzdCwgUERTSV80Q19tZWFuX3Jhc3QsIGZyZXFfZGlmZl9yYXN0LCBkdXJfZGlmZl9yYXN0LCByZXNhbXBsZShhbnVyYW5fc3IsIFBEU0lfNENfbWVhbl9yYXN0KSkgClBEU0lfYWJfcmFzdF9jcm9wIDwtIHJhc3Rlcjo6bWFzayhjcm9wKFBEU0lfYWJfcmFzdCwgZXh0ZW50KHdvcmxkKSksIHdvcmxkKSAjIGNyb3AgCgpQRFNJX2FiX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKFBEU0lfYWJfcmFzdF9jcm9wKSkgJT4lCiAgZHBseXI6OnJlbmFtZShQRFNJX2N1ciA9ICJsYXllci4xIiwKICAgICAgICAgICAgICAgIFBEU0lfMkMgID0gImxheWVyLjIiLAogICAgICAgICAgICAgICAgUERTSV80QyAgPSAibGF5ZXIuMyIsCiAgICAgICAgICAgICAgICBmcmVxX2N1ciA9ICJtZWFuX2N1cnIuMSIsCiAgICAgICAgICAgICAgICBmcmVxXzJDICA9ICJtZWFuXzJDLjEiLAogICAgICAgICAgICAgICAgZnJlcV80QyAgPSAibWVhbl80Qy4xIiwKICAgICAgICAgICAgICAgIGR1cl9jdXIgID0gIm1lYW5fY3Vyci4yIiwKICAgICAgICAgICAgICAgIGR1cl8yQyAgID0gIm1lYW5fMkMuMiIsCiAgICAgICAgICAgICAgICBkdXJfNEMgICA9ICJtZWFuXzRDLjIiLAogICAgICAgICAgICAgICAgc3BfbiAgICAgPSAibGF5ZXIuNCIpICU+JQogIGZpbHRlcihzcF9uICE9ICJOQSIpCgpjb2xvdXJzX1BEU0kgPC0gUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDksICJSZEJ1IikKCiMgSW50ZW5zaXR5ClBEU0lfY3VyX3Bsb3QgPC0gUERTSV9hYl9kZiAlPiUKICBkcGx5cjo6bXV0YXRlKFBEU0lfY3VyX2NhdCA9IGNhc2Vfd2hlbigKICAgIFBEU0lfY3VyID49IDIgJiBQRFNJX2N1ciA8IDMgfiAnMicsICAKICAgIFBEU0lfY3VyID49IDEgJiBQRFNJX2N1ciA8IDIgfiAnMScsICAKICAgIFBEU0lfY3VyID49IC0xICYgUERTSV9jdXIgPCAxIH4gJzAnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUERTSV9jdXJfY2F0ID0gZmFjdG9yKFBEU0lfY3VyX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCcwJywgJzEnLCAnMicpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZmlsdGVyKFBEU0lfY3VyX2NhdCAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IFBEU0lfY3VyX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0Y3RjdGNyIsICIjRDFFNUYwIiAsIiM5MkM1REUiKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJNZWFuIFBEU0kgaW50ZW5zaXR5ICgxOTcw4oCTMjAwMCkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KClBEU0lfMkNfcGxvdCA8LSBQRFNJX2FiX2RmICU+JQogIGRwbHlyOjptdXRhdGUoUERTSV8yQ19jYXQgPSBjYXNlX3doZW4oCiAgICBQRFNJXzJDID49IDQgfiAiNCIsIAogICAgUERTSV8yQyA+PSAzICYgUERTSV8yQyA8IDQgfiAnMycsCiAgICBQRFNJXzJDID49IDIgJiBQRFNJXzJDIDwgMyB+ICcyJywgIAogICAgUERTSV8yQyA+PSAxICYgUERTSV8yQyA8IDIgfiAnMScsICAKICAgIFBEU0lfMkMgPj0gLTEgJiBQRFNJXzJDIDwgMSB+ICcwJywKICAgIFBEU0lfMkMgPj0gLTIgJiBQRFNJXzJDIDwgLTEgfiAnLTEnLAogICAgUERTSV8yQyA+PSAtMyAmIFBEU0lfMkMgPCAtMiB+ICctMicsCiAgICBQRFNJXzJDID49IC00ICYgUERTSV8yQyA8IC0zIH4gJy0zJywgICAKICAgIFBEU0lfMkMgPCAtNCB+ICctNCcgCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUERTSV8yQ19jYXQgPSBmYWN0b3IoUERTSV8yQ19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnLTQnLCAnLTMnLCAnLTInLCAnLTEnLCAnMCcsICcxJywgJzInLCAnMycsICc0JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBmaWx0ZXIoUERTSV8yQ19jYXQgIT0gIk5BIikgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBQRFNJXzJDX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3Vyc19QRFNJKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoIk1lYW4gUERTSSBpbnRlbnNpdHkgKCsywrBDKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKUERTSV80Q19wbG90IDwtIFBEU0lfYWJfZGYgJT4lCiAgZHBseXI6Om11dGF0ZShQRFNJXzRDX2NhdCA9IGNhc2Vfd2hlbigKICAgIFBEU0lfNEMgPj0gNCB+ICI0IiwgCiAgICBQRFNJXzRDID49IDMgJiBQRFNJXzRDIDwgNCB+ICczJywKICAgIFBEU0lfNEMgPj0gMiAmIFBEU0lfNEMgPCAzIH4gJzInLCAgCiAgICBQRFNJXzRDID49IDEgJiBQRFNJXzRDIDwgMiB+ICcxJywgIAogICAgUERTSV80QyA+PSAtMSAmIFBEU0lfNEMgPCAxIH4gJzAnLAogICAgUERTSV80QyA+PSAtMiAmIFBEU0lfNEMgPCAtMSB+ICctMScsCiAgICBQRFNJXzRDID49IC0zICYgUERTSV80QyA8IC0yIH4gJy0yJywKICAgIFBEU0lfNEMgPj0gLTQgJiBQRFNJXzRDIDwgLTMgfiAnLTMnLCAgIAogICAgUERTSV80QyA8IC00IH4gJy00JyAKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQRFNJXzRDX2NhdCA9IGZhY3RvcihQRFNJXzRDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCctNCcsICctMycsICctMicsICctMScsICcwJywgJzEnLCAnMicsICczJywgJzQnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQogIGZpbHRlcihQRFNJXzRDX2NhdCAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IFBEU0lfNENfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvdXJzX1BEU0ksIG5hbWUgPSAiUERTSSIsIGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFLCBucm93ID0gMSkpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZSgiTWVhbiBQRFNJIGludGVuc2l0eSAoKzTCsEMpIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIAogICAgICAgIGxlZ2VuZC5rZXkuaGVpZ2h0PSB1bml0KDAuMiwgJ2NtJyksCiAgICAgICAgbGVnZW5kLmtleS53aWR0aD0gdW5pdCgwLjIsICdjbScpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgppbnRfbGVnZW5kIDwtIGNvd3Bsb3Q6OmdldF9sZWdlbmQoUERTSV80Q19wbG90KQoKaW50X3Byb3cgPC0gY293cGxvdDo6cGxvdF9ncmlkKFBEU0lfY3VyX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIFBEU0lfMkNfcGxvdCArICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIFBEU0lfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgYWxpZ24gPSAidiIsIG5jb2wgPSAzLCBsYWJlbHMgPSBjKCdhJywgJ2InLCAnYycpKSAKCmludF9wbG90cyA8LSBjb3dwbG90OjpwbG90X2dyaWQoaW50X3Byb3csIGludF9sZWdlbmQsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMSwgLjEpKQoKIyBGcmVxdWVuY3kKZnJlcV9jdXJfcGxvdCA8LSBQRFNJX2FiX2RmICU+JQogIGRwbHlyOjptdXRhdGUoZnJlcV9jdXJfY2F0ID0gY2FzZV93aGVuKAogICAgZnJlcV9jdXIgPiAwLjEgJiBmcmVxX2N1ciA8IDEgfiAnPDEnCiAgKSkgJT4lCiAgZmlsdGVyKGZyZXFfY3VyX2NhdCAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGZyZXFfY3VyX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3NwZGYsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gIiNlZGVkZWQiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoIk1lYW4gZHJvdWdodCBmcmVxdWVuY3kgKDE5NzDigJMyMDAwKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKZnJlcV8yQ19wbG90IDwtIFBEU0lfYWJfZGYgJT4lCiAgZHBseXI6Om11dGF0ZShmcmVxXzJDX2NhdCA9IGNhc2Vfd2hlbigKICAgIGZyZXFfMkMgPj0gMTAgfiAiMTAtMTIiLCAKICAgIGZyZXFfMkMgPj0gOCAmIGZyZXFfMkMgPCAxMCB+ICc4LTEwJywKICAgIGZyZXFfMkMgPj0gNiAmIGZyZXFfMkMgPCA4IH4gJzYtOCcsICAKICAgIGZyZXFfMkMgPj0gNCAmIGZyZXFfMkMgPCA2IH4gJzQtNicsICAKICAgIGZyZXFfMkMgPj0gMiAmIGZyZXFfMkMgPCA0IH4gJzItNCcsCiAgICBmcmVxXzJDID49IDEgJiBmcmVxXzJDIDwgMiB+ICcxLTInLAogICAgZnJlcV8yQyA+IDAuMSAmIGZyZXFfMkMgPCAxIH4gJzwxJwogICkpICU+JSAKICBkcGx5cjo6bXV0YXRlKGZyZXFfMkNfY2F0ID0gZmFjdG9yKGZyZXFfMkNfY2F0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnMTAtMTInLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAnPDEnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZmlsdGVyKGZyZXFfMkNfY2F0ICE9ICJOQSIpICU+JQogIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gZnJlcV8yQ19jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM2NzAwMUYiLCAiI0IyMTgyQiIsICIjRDY2MDREIiwgIiNGNEE1ODIiLCAiI0ZEREJDNyIsICIjRkFFOURGIiwgIiNGN0Y3RjciKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJNZWFuIGRyb3VnaHQgZnJlcXVlbmN5ICgrMsKwQykiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCmZyZXFfNENfcGxvdCA8LSBQRFNJX2FiX2RmICU+JQogIGRwbHlyOjptdXRhdGUoZnJlcV80Q19jYXQgPSBjYXNlX3doZW4oCiAgICBmcmVxXzRDID49IDEwIH4gIjEwLTEyIiwgCiAgICBmcmVxXzRDID49IDggJiBmcmVxXzRDIDwgMTAgfiAnOC0xMCcsCiAgICBmcmVxXzRDID49IDYgJiBmcmVxXzRDIDwgOCB+ICc2LTgnLCAgCiAgICBmcmVxXzRDID49IDQgJiBmcmVxXzRDIDwgNiB+ICc0LTYnLCAgCiAgICBmcmVxXzRDID49IDIgJiBmcmVxXzRDIDwgNCB+ICcyLTQnLAogICAgZnJlcV80QyA+PSAxICYgZnJlcV80QyA8IDIgfiAnMS0yJywKICAgIGZyZXFfNEMgPiAwLjEgJiBmcmVxXzRDIDwgMSB+ICc8MScKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShmcmVxXzRDX2NhdCA9IGZhY3RvcihmcmVxXzRDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJzEwLTEyJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgJzwxJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQogIGZpbHRlcihmcmVxXzRDX2NhdCAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGZyZXFfNENfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfc3BkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiksIG5hbWUgPSAiTW9udGhzIiwgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUsIG5yb3cgPSAxKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJNZWFuIGRyb3VnaHQgZnJlcXVlbmN5ICgrNMKwQykiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwgCiAgICAgICAgbGVnZW5kLmtleS5oZWlnaHQ9IHVuaXQoMC4yLCAnY20nKSwKICAgICAgICBsZWdlbmQua2V5LndpZHRoPSB1bml0KDAuMiwgJ2NtJyksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCmZyZXFfbGVnZW5kIDwtIGNvd3Bsb3Q6OmdldF9sZWdlbmQoZnJlcV80Q19wbG90KQoKZnJlcV9wcm93IDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChmcmVxX2N1cl9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBmcmVxXzJDX3Bsb3QgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBmcmVxXzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLCAKICAgICAgICAgICAgICAgICAgIGFsaWduID0gInYiLCBuY29sID0gMywgbGFiZWxzID0gYygnZCcsICdlJywgJ2YnKSkgCgpmcmVxX3Bsb3RzIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChmcmVxX3Byb3csIGZyZXFfbGVnZW5kLCBuY29sID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKCgojIER1cmF0aW9uCmR1cl9jdXJfcGxvdCA8LSBQRFNJX2FiX2RmICU+JQogIGRwbHlyOjptdXRhdGUoZHVyX2N1cl9jYXQgPSBjYXNlX3doZW4oCiAgICBkdXJfY3VyID49IDIgJiBkdXJfY3VyIDwgNCB+ICcyLTQnLAogICAgIGR1cl9jdXIgPj0gMSAmIGR1cl9jdXIgPCAyIH4gJzEtMicsCiAgICBkdXJfY3VyID4gMC4xICYgZHVyX2N1ciA8IDEgfiAnPDEnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZHVyX2N1cl9jYXQgPSBmYWN0b3IoZHVyX2N1cl9jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnMi00JywgJzEtMicsICc8MScpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZmlsdGVyKGR1cl9jdXJfY2F0ICE9ICJOQSIpICU+JQogIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gZHVyX2N1cl9jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IikpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZSgiTWVhbiBkcm91Z2h0IGR1cmF0aW9uICgxOTcw4oCTMjAwMCkiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYwLCA5MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTgwLCAxODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCmR1cl8yQ19wbG90IDwtIFBEU0lfYWJfZGYgJT4lCiAgZHBseXI6Om11dGF0ZShkdXJfMkNfY2F0ID0gY2FzZV93aGVuKAogICAgZHVyXzJDID49IDEwIH4gIj4xMCIsIAogICAgZHVyXzJDID49IDggJiBkdXJfMkMgPCAxMCB+ICc4LTEwJywKICAgIGR1cl8yQyA+PSA2ICYgZHVyXzJDIDwgOCB+ICc2LTgnLCAgCiAgICBkdXJfMkMgPj0gNCAmIGR1cl8yQyA8IDYgfiAnNC02JywgIAogICAgZHVyXzJDID49IDIgJiBkdXJfMkMgPCA0IH4gJzItNCcsCiAgICBkdXJfMkMgPj0gMSAmIGR1cl8yQyA8IDIgfiAnMS0yJywKICAgIGR1cl8yQyA+IDAuMSAmIGR1cl8yQyA8IDEgfiAnPDEnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZHVyXzJDX2NhdCA9IGZhY3RvcihkdXJfMkNfY2F0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJz4xMCcsICc4LTEwJywgJzYtOCcsICc0LTYnLCAnMi00JywgJzEtMicsICc8MScpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSklPiUKICBmaWx0ZXIoZHVyXzJDX2NhdCAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGR1cl8yQ19jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM2NzAwMUYiLCAiI0IyMTgyQiIsICIjRDY2MDREIiwgIiNGNEE1ODIiLCAiI0ZEREJDNyIsICIjRkFFOURGIiwgIiNGN0Y3RjciKSkgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJNZWFuIGRyb3VnaHQgZHVyYXRpb24gKCsywrBDKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjAsIDkwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xODAsIDE4MCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKZHVyXzRDX3Bsb3QgPC0gUERTSV9hYl9kZiAlPiUKICBkcGx5cjo6bXV0YXRlKGR1cl80Q19jYXQgPSBjYXNlX3doZW4oCiAgICBkdXJfNEMgPj0gMTAgfiAiPjEwIiwgCiAgICBkdXJfNEMgPj0gOCAmIGR1cl80QyA8IDEwIH4gJzgtMTAnLAogICAgZHVyXzRDID49IDYgJiBkdXJfNEMgPCA4IH4gJzYtOCcsICAKICAgIGR1cl80QyA+PSA0ICYgZHVyXzRDIDwgNiB+ICc0LTYnLCAgCiAgICBkdXJfNEMgPj0gMiAmIGR1cl80QyA8IDQgfiAnMi00JywKICAgIGR1cl80QyA+PSAxICYgZHVyXzRDIDwgNCB+ICcxLTInLAogICAgZHVyXzRDID4gMC4xICYgZHVyXzRDIDwgMSB+ICc8MScKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShkdXJfNENfY2F0ID0gZmFjdG9yKGR1cl80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjEwJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgJzwxJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBmaWx0ZXIoZHVyXzRDX2NhdCAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGR1cl80Q19jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9zcGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM2NzAwMUYiLCAiI0IyMTgyQiIsICIjRDY2MDREIiwgIiNGNEE1ODIiLCAiI0ZEREJDNyIsICIjRkFFOURGIiwgIiNGN0Y3RjciKSwgbmFtZSA9ICJNb250aHMiLCBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSwgbnJvdyA9IDEpKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoIk1lYW4gZHJvdWdodCBkdXJhdGlvbiAoKzTCsEMpIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MCwgOTApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE4MCwgMTgwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIAogICAgICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC4yLCAnY20nKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKZHVyX2xlZ2VuZCA8LSBjb3dwbG90OjpnZXRfbGVnZW5kKGR1cl80Q19wbG90KQoKZHVyX3Byb3cgPC0gY293cGxvdDo6cGxvdF9ncmlkKGR1cl9jdXJfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgZHVyXzJDX3Bsb3QgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwgCiAgICAgICAgICAgICAgICAgICBkdXJfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogICAgICAgICAgICAgICAgICAgYWxpZ24gPSAidiIsIG5jb2wgPSAzLCBsYWJlbHMgPSBjKCdnJywgJ2gnLCAnaScpKSAKCmR1cl9wbG90cyA8LSBjb3dwbG90OjpwbG90X2dyaWQoZHVyX3Byb3csIGR1cl9sZWdlbmQsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMSwgLjEpKQoKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChpbnRfcGxvdHMsIGZyZXFfcGxvdHMsIGR1cl9wbG90cywgbmNvbCA9IDEpCmBgYAoKKipGaWcuIFMyLioqIE1lYW4gbW9udGhseSBQYWxtZXIgRHJvdWdodCBTZXZlcml0eSBJbmRleCAoUERTSSkgc2VsZi1jYWxpYnJhdGVkIHdpdGggUGVubWFu4oCTTW9udGVpdGggcG90ZW50aWFsIGV2YXBvdHJhbnNwaXJhdGlvbiBmcm9tICgqKmEqKikgMTk3MOKAkzIwMDAsIGFuZCBmcm9tIDIwODAtMjEwMCB1bmRlciAoKipiKiopIHVuZGVyIGFuIGludGVybWVkaWF0ZSBlbWlzc2lvbiBzY2VuYXJpbyAoU2hhcmVkIFNvY2lvZWNvbm9taWMgUGF0aHdheXMgMiAtIDQuNTsgU1NQMi00LjUpLCBhbmQgKCoqYyoqKSB1bmRlciBhIGhpZ2ggZW1pc3Npb24gc2NlbmFyaW8gKFNTUDUtOC41KS4gTWVhbiB5ZWFybHkgZnJlcXVlbmN5IG9mIG1vZGVyYXRlIHRvIGV4dHJlbWUgZHJvdWdodCAoUERTSSA8IC0yKSBmcm9tICgqKmQqKikgMTk3MOKAkzIwMDAsIGFuZCBmcm9tIDIwODAtMjEwMCAoKiplKiopIHVuZGVyIGFuIGludGVybWVkaWF0ZSBlbWlzc2lvbiBzY2VuYXJpbyAoU1NQMi00LjUpLCBhbmQgKCoqZioqKSB1bmRlciBhIGhpZ2ggZW1pc3Npb24gc2NlbmFyaW8gKFNTUDUtOC41KS4gTWVhbiBkdXJhdGlvbiBvZiBtb2RlcmF0ZSB0byBleHRyZW1lIGRyb3VnaHQgKFBEU0kgPCAtMikgZnJvbSAoKipnKiopIDE5NzDigJMyMDAwLCBhbmQgZnJvbSAyMDgwLTIxMDAgKCoqaCoqKSB1bmRlciBhbiBpbnRlcm1lZGlhdGUgZW1pc3Npb24gc2NlbmFyaW8gKFNTUDItNC41KSwgYW5kICgqKmkqKikgdW5kZXIgYSBoaWdoIGVtaXNzaW9uIHNjZW5hcmlvIChTU1A1LTguNSkuCgojIyBTdW1tYXJ5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19CgojIyMgRWNvdHlwZSBBSSBkaXN0cmlidXRpb24gey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgpNZWFuIMKxIHMuZC4gYXJpZGl0eSBpbmRleCBvY2N1cGllZCBieSBkaWZmZXJlbnQgYW51cmFuIGVjb3R5cGVzLgoKYGBge3IgZWNvdHlwZSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KYWlfc3BfZGYgJT4lCiAgZHBseXI6OmZpbHRlcihhcmlkaXR5IDw9MykgJT4lCiAgZHBseXI6OnNlbGVjdChhcmlkaXR5LCBzcGVjaWVzX246c3RyZWFtX24pICU+JQogIHRpZHlyOjpwaXZvdF9sb25nZXIoIWFyaWRpdHksIG5hbWVzX3RvID0gImVjb3R5cGUiLCB2YWx1ZXNfdG8gPSAibWVhbiIpICU+JQogIGRwbHlyOjpmaWx0ZXIoZWNvdHlwZSAhPSAic3BlY2llc19uIikgJT4lCiAgZHJvcF9uYShtZWFuKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoZWNvdHlwZSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShtZWFuID0gbWVhbihhcmlkaXR5KSwKICAgICAgICAgICAgICAgICAgIHNkICAgPSBzZChhcmlkaXR5KSkgJT4lCiAgZHBseXI6Om11dGF0ZShlY290eXBlID0gc3Vic3RyKGVjb3R5cGUsMSxuY2hhcihlY290eXBlKS0yKSwKICAgICAgICAgICAgICAgIG1lYW4gICAgPSBmb3JtYXQocm91bmQobWVhbiwgMiksIG5zbWFsbCA9IDIpLAogICAgICAgICAgICAgICAgc2QgICAgICA9IGZvcm1hdChyb3VuZChzZCwgMiksIG5zbWFsbCA9IDIpLAogICAgICAgICAgICAgICAgYXJpZGl0eSA9IHBhc3RlKG1lYW4sIHNkLCBzZXAgPSAiIMKxICIpLAogICAgICAgICAgICAgICAgZWNvdHlwZSA9IGNhc2Vfd2hlbigKICAgIGVjb3R5cGUgPT0gInN0cmVhbSIgICAgfiAiU3RyZWFtLWR3ZWxsaW5nIiwKICAgIGVjb3R5cGUgPT0gImFyYm9yZWFsIiAgfiAiQXJib3JlYWwiLAogICAgZWNvdHlwZSA9PSAic2VtaV9hcSIgIH4gIlNlbWktYXF1YXRpYyIsCiAgICBlY290eXBlID09ICJhcXVhdGljIiAgfiAiQXF1YXRpYyIsCiAgICBlY290eXBlID09ICJncm91bmQiICB+ICJHcm91bmQtZHdlbGxpbmciLAogICAgZWNvdHlwZSA9PSAiZm9zc29yaWFsIiB+ICJGb3Nzb3JpYWwiKSkgJT4lCiAgZHBseXI6OnNlbGVjdChlY290eXBlLCBhcmlkaXR5KSAlPiUKICBkcGx5cjo6YXJyYW5nZShkZXNjKGFyaWRpdHkpKSAlPiUKICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygiRWNvdHlwZSIsICJBSSAobWVhbiDCsSBzLmQuKSIpKQpgYGAKCioqKgoKIyMjIDLCsEMgQUkgcmlzayB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKClBlcmNlbnQgY2hhbmdlIGluIGFyaWRpdHkgYnkgMjA4MOKAkzIxMDAgKCsgMsKwQykgcmVsYXRpdmUgdG8gY3VycmVudCBjbGltYXRlICgxOTgx4oCTMjAxMCkgZm9yIGFsbCBhbnVyYW5zIGFuZCBhbHNvIGJ5IGVjb3R5cGUuCgpgYGB7ciBhaSBzdW0gMiwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBjYWxjdWxhdGUgcmVsYXRpdmUgY2hhbmdlIHdpdGggZnV0dXJlIHNjZW5hcmlvCmFpX3NwX3N1bSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9jaGFuZ2UgICAgICAgPSAoYWlfMkNfc3Bfc3VtJHNwZWNpZXNfbiAtIHNwZWNpZXNfbikgLyBzcGVjaWVzX24gKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2NoYW5nZSAgID0gKGFpXzJDX3NwX3N1bSRhcXVhdGljX24gLSBhcXVhdGljX24pIC8gYXF1YXRpY19uICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfY2hhbmdlICA9IChhaV8yQ19zcF9zdW0kYXJib3JlYWxfbiAtIGFyYm9yZWFsX24pIC8gYXJib3JlYWxfbiAqIDEwMCwKICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9jaGFuZ2UgPSAoYWlfMkNfc3Bfc3VtJGZvc3NvcmlhbF9uIC0gZm9zc29yaWFsX24pIC8gZm9zc29yaWFsX24gKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfY2hhbmdlICAgID0gKGFpXzJDX3NwX3N1bSRncm91bmRfbiAtIGdyb3VuZF9uKSAvIGdyb3VuZF9uICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9jaGFuZ2UgICA9IChhaV8yQ19zcF9zdW0kc2VtaV9hcV9uIC0gc2VtaV9hcV9uKSAvIHNlbWlfYXFfbiAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9jaGFuZ2UgICAgPSAoYWlfMkNfc3Bfc3VtJHN0cmVhbV9uIC0gc3RyZWFtX24pIC8gc3RyZWFtX24gKiAxMDApICU+JQogIGRwbHlyOjpzZWxlY3QoYyhjYXRlZ29yeSwgYWxsX2NoYW5nZTpzdHJlYW1fY2hhbmdlKSkgJT4lCiAga25pdHI6OmthYmxlKGNvbC5uYW1lcyA9IGMoIkVjb3R5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsICglKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFxdWF0aWMgMsKwQyAoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJib3JlYWwgMsKwQyAoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRm9zc29yaWFsIDLCsEMoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR3JvdW5kLWR3ZWxsaW5nIDLCsEMgKCUpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlbWktYXF1YXRpYyAywrBDICglKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdHJlYW0tZHdlbGxpbmcgMsKwQyAoJSkiKSwKICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICMgMiBkZWNpbWFsIHBsYWNlcwpgYGAKCioqKgoKIyMjIDTCsEMgQUkgcmlzayB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKClBlcmNlbnQgY2hhbmdlIGluIGFyaWRpdHkgYnkgMjA4MOKAkzIxMDAgKCsgNMKwQykgcmVsYXRpdmUgdG8gY3VycmVudCBjbGltYXRlICgxOTgx4oCTMjAxMCkgZm9yIGFsbCBhbnVyYW5zIGFuZCBhbHNvIGJ5IGVjb3R5cGUuCgpgYGB7ciBhaSBzdW0gNCwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBjYWxjdWxhdGUgcmVsYXRpdmUgY2hhbmdlIHdpdGggZnV0dXJlIHNjZW5hcmlvCmFpX3NwX3N1bSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9jaGFuZ2UgICAgICAgPSAoYWlfNENfc3Bfc3VtJHNwZWNpZXNfbiAtIHNwZWNpZXNfbikgLyBzcGVjaWVzX24gKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2NoYW5nZSAgID0gKGFpXzRDX3NwX3N1bSRhcXVhdGljX24gLSBhcXVhdGljX24pIC8gYXF1YXRpY19uICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfY2hhbmdlICA9IChhaV80Q19zcF9zdW0kYXJib3JlYWxfbiAtIGFyYm9yZWFsX24pIC8gYXJib3JlYWxfbiAqIDEwMCwKICAgICAgICAgICAgICAgIGZvc3NvcmlhbF9jaGFuZ2UgPSAoYWlfNENfc3Bfc3VtJGZvc3NvcmlhbF9uIC0gZm9zc29yaWFsX24pIC8gZm9zc29yaWFsX24gKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfY2hhbmdlICAgID0gKGFpXzRDX3NwX3N1bSRncm91bmRfbiAtIGdyb3VuZF9uKSAvIGdyb3VuZF9uICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9jaGFuZ2UgICA9IChhaV80Q19zcF9zdW0kc2VtaV9hcV9uIC0gc2VtaV9hcV9uKSAvIHNlbWlfYXFfbiAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9jaGFuZ2UgICAgPSAoYWlfNENfc3Bfc3VtJHN0cmVhbV9uIC0gc3RyZWFtX24pIC8gc3RyZWFtX24gKiAxMDApICU+JQogIGRwbHlyOjpzZWxlY3QoYyhjYXRlZ29yeSwgYWxsX2NoYW5nZTpzdHJlYW1fY2hhbmdlKSkgJT4lCiAga25pdHI6OmthYmxlKGNvbC5uYW1lcyA9IGMoIkVjb3R5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWxsICglKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFxdWF0aWMgMsKwQyAoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJib3JlYWwgMsKwQyAoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRm9zc29yaWFsIDLCsEMoJSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR3JvdW5kLWR3ZWxsaW5nIDLCsEMgKCUpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNlbWktYXF1YXRpYyAywrBDICglKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdHJlYW0tZHdlbGxpbmcgMsKwQyAoJSkiKSwKICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICMgMiBkZWNpbWFsIHBsYWNlcwpgYGAKCioqKgoKIyMjIDLCsEMgUERTSSAgcmlzayB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKClBlcmNlbnQgY2hhbmdlIGluIGRyb3VnaHQgaW50ZW5zaXR5ICjOlFBEU0kpLCBkcm91Z2h0IGZyZXF1ZW5jeSAozpRGcmVxdWVuY3kpLCBhbmQgZHJvdWdodCBkdXJhdGlvbiAozpREdXJhdGlvbikgYnkgMjA4MOKAkzIwOTkgKCsgMsKwQyBzY2VuYXJpbykgcmVsYXRpdmUgdG8gY3VycmVudCBjbGltYXRlICgxOTcw4oCTMjAwMCkgaW4gZ3JpZCBjZWxscyBvY2N1cGllZCBieSBhbnVyYW5zIGFuZCBhbHNvIGJ5IGVjb3R5cGUuCgpgYGB7ciBQRFNJIHN1bSAyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojSW50ZW5zaXR5ClBEU0lfc3BfMkMgJT4lCiAgZHBseXI6OnNlbGVjdChjKGNoYW5nZV8yQywgYWxsX2ZyZXE6c3RyZWFtX2ZyZXEpKSAlPiUKICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygizpRQRFNJIiwgIkFsbCAoJSkiLCAiQXF1YXRpYyAoJSkiLCAiQXJib3JlYWwgKCUpIiwgIkZvc3NvcmlhbCAoJSkiLCAiR3JvdW5kLWR3ZWxsaW5nICglKSIsICJTZW1pLWFxdWF0aWMgKCUpIiwgIlN0cmVhbS1kd2VsbGluZyAoJSkiKSwKICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICMgMiBkZWNpbWFsIHBsYWNlcwoKIyBGcmVxdWVuY3kKZnJlcV8yQ19kaWZmX2RmIDwtIGZyZXFfZGlmZl9kZiAlPiUKICBkcGx5cjo6c2VsZWN0KHgsIHksIGRpZmZfMkMpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl8yQ19jYXQgPSBjYXNlX3doZW4oCiAgICBkaWZmXzJDID49IDEwIH4gIjEwLTEyIiwgCiAgICBkaWZmXzJDID49IDggJiBkaWZmXzJDIDwgMTAgfiAnOC0xMCcsCiAgICBkaWZmXzJDID49IDYgJiBkaWZmXzJDIDwgOCB+ICc2LTgnLCAgCiAgICBkaWZmXzJDID49IDQgJiBkaWZmXzJDIDwgNiB+ICc0LTYnLCAgCiAgICBkaWZmXzJDID49IDIgJiBkaWZmXzJDIDwgNCB+ICcyLTQnLAogICAgZGlmZl8yQyA+PSAxICYgZGlmZl8yQyA8IDIgfiAnMS0yJywKICAgIGRpZmZfMkMgPiAwICYgZGlmZl8yQyA8IDEgfiAnMC0xJywKICAgIGRpZmZfMkMgPj0gLTEgJiBkaWZmXzJDIDwgMCB+ICctMC0xJywKICAgIGRpZmZfMkMgPj0gLTIgJiBkaWZmXzJDIDwgLTEgfiAnLTEtMicsCiAgICBkaWZmXzJDID49IC00ICYgZGlmZl8yQyA8IC0yIH4gJy0yLTQnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl8yQ19jYXQgPSBmYWN0b3IoZGlmZl8yQ19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnMTAtMTInLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAnMC0xJywgJy0wLTEnLCAnLTEtMicsICctMi00JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKZnJlcV9zcF8yQ19kZiA8LSBhbnVyYW5fc3JfZGYgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZnJlcV8yQ19kaWZmX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhcXVhdGljX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhcmJvcmVhbF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZm9zc29yaWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihncm91bmRfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKHNlbWlfYXFfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKHN0cmVhbV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lCiAgZmlsdGVyKGRpZmZfMkNfY2F0ICE9ICJOQSIgJiBzcGVjaWVzX24gIT0gIk5BIikKCmRhdGEuZnJhbWUoZnJlcV9zcF8yQ19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoZGlmZl8yQ19jYXQpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2Uoc3BlY2llc19uICAgPSBsZW5ndGgoc3BlY2llc19uWyFpcy5uYShzcGVjaWVzX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFxdWF0aWNfbiAgID0gbGVuZ3RoKGFxdWF0aWNfblshaXMubmEoYXF1YXRpY19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmJvcmVhbF9uICA9IGxlbmd0aChhcmJvcmVhbF9uWyFpcy5uYShhcmJvcmVhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfbiA9IGxlbmd0aChmb3Nzb3JpYWxfblshaXMubmEoZm9zc29yaWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9uICAgID0gbGVuZ3RoKGdyb3VuZF9uWyFpcy5uYShncm91bmRfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtaV9hcV9uICAgPSBsZW5ndGgoc2VtaV9hcV9uWyFpcy5uYShzZW1pX2FxX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbV9uICAgID0gbGVuZ3RoKHN0cmVhbV9uWyFpcy5uYShzdHJlYW1fbildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoYWxsX2ZyZXEgICAgICAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFxdWF0aWNfZnJlcSAgID0gYXF1YXRpY19uIC8gc3VtKGFxdWF0aWNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcmJvcmVhbF9mcmVxICA9IGFyYm9yZWFsX24gLyBzdW0oYXJib3JlYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfZnJlcSA9IGZvc3NvcmlhbF9uIC8gc3VtKGZvc3NvcmlhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGdyb3VuZF9mcmVxICAgID0gZ3JvdW5kX24gLyBzdW0oZ3JvdW5kX24pICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9mcmVxICAgPSBzZW1pX2FxX24gLyBzdW0oc2VtaV9hcV9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9mcmVxICAgID0gc3RyZWFtX24gLyBzdW0oc3RyZWFtX24pICogMTAwKSAlPiUKICBkcGx5cjo6c2VsZWN0KGMoZGlmZl8yQ19jYXQsIGFsbF9mcmVxOnN0cmVhbV9mcmVxKSkgJT4lCiAgIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCLOlEZyZXF1ZW5jeSAobW9udGhzKSIsICJBbGwgKCUpIiwgIkFxdWF0aWMgKCUpIiwgIkFyYm9yZWFsICglKSIsICJGb3Nzb3JpYWwgKCUpIiwgIkdyb3VuZC1kd2VsbGluZyAoJSkiLCAiU2VtaS1hcXVhdGljICglKSIsICJTdHJlYW0tZHdlbGxpbmcgKCUpIiksCiAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKSAjIDIgZGVjaW1hbCBwbGFjZXMKCiMgRHVyYXRpb24KZHVyXzJDX2RpZmZfZGYgPC0gZHVyX2RpZmZfZGYgJT4lCiAgZHBseXI6OnNlbGVjdCh4LCB5LCBkaWZmXzJDKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRpZmZfMkNfY2F0ID0gY2FzZV93aGVuKAogICAgZGlmZl8yQyA+PSAxMCB+ICI+MTAiLCAKICAgIGRpZmZfMkMgPj0gOCAmIGRpZmZfMkMgPCAxMCB+ICc4LTEwJywKICAgIGRpZmZfMkMgPj0gNiAmIGRpZmZfMkMgPCA4IH4gJzYtOCcsICAKICAgIGRpZmZfMkMgPj0gNCAmIGRpZmZfMkMgPCA2IH4gJzQtNicsICAKICAgIGRpZmZfMkMgPj0gMiAmIGRpZmZfMkMgPCA0IH4gJzItNCcsCiAgICBkaWZmXzJDID49IDEgJiBkaWZmXzJDIDwgMiB+ICcxLTInLAogICAgZGlmZl8yQyA+IDAgJiBkaWZmXzJDIDwgMSB+ICcwLTEnLAogICAgZGlmZl8yQyA+PSAtMSAmIGRpZmZfMkMgPCAwIH4gJy0wLTEnLAogICAgZGlmZl8yQyA+PSAtMiAmIGRpZmZfMkMgPCAtMSB+ICctMS0yJywKICAgIGRpZmZfMkMgPj0gLTQgJiBkaWZmXzJDIDwgLTIgfiAnLTItNCcsCiAgICBkaWZmXzJDID49IC02ICYgZGlmZl8yQyA8IC00IH4gJy00LTYnLAogICAgZGlmZl8yQyA+PSAtOCAmIGRpZmZfMkMgPCAtNiB+ICctNi04JywKICAgIGRpZmZfMkMgPj0gLTEwICYgZGlmZl8yQyA8IC04IH4gJy04LTEwJywgICAKICAgIGRpZmZfMkMgPCAtMTAgfiAnPC0xMCcgCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl8yQ19jYXQgPSBmYWN0b3IoZGlmZl8yQ19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjEwJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgJzAtMScsICctMC0xJywgJy0xLTInLCAnLTItNCcsICctNC02JywgJy02LTgnLCAnLTgtMTAnLCAnPC0xMCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkKCmR1cl9zcF8yQ19kZiA8LSBhbnVyYW5fc3JfZGYgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZHVyXzJDX2RpZmZfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFxdWF0aWNfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFyYm9yZWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihmb3Nzb3JpYWxfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGdyb3VuZF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc2VtaV9hcV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc3RyZWFtX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUKICBmaWx0ZXIoZGlmZl8yQ19jYXQgIT0gIk5BIiAmIHNwZWNpZXNfbiAhPSAiTkEiKQoKZGF0YS5mcmFtZShkdXJfc3BfMkNfZGYgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGRpZmZfMkNfY2F0KSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiAgID0gbGVuZ3RoKHNwZWNpZXNfblshaXMubmEoc3BlY2llc19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcXVhdGljX24gICA9IGxlbmd0aChhcXVhdGljX25bIWlzLm5hKGFxdWF0aWNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJib3JlYWxfbiAgPSBsZW5ndGgoYXJib3JlYWxfblshaXMubmEoYXJib3JlYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9zc29yaWFsX24gPSBsZW5ndGgoZm9zc29yaWFsX25bIWlzLm5hKGZvc3NvcmlhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91bmRfbiAgICA9IGxlbmd0aChncm91bmRfblshaXMubmEoZ3JvdW5kX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbWlfYXFfbiAgID0gbGVuZ3RoKHNlbWlfYXFfblshaXMubmEoc2VtaV9hcV9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1fbiAgICA9IGxlbmd0aChzdHJlYW1fblshaXMubmEoc3RyZWFtX24pXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9mcmVxICAgICAgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2ZyZXEgICA9IGFxdWF0aWNfbiAvIHN1bShhcXVhdGljX24pICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfZnJlcSAgPSBhcmJvcmVhbF9uIC8gc3VtKGFyYm9yZWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZm9zc29yaWFsX2ZyZXEgPSBmb3Nzb3JpYWxfbiAvIHN1bShmb3Nzb3JpYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfZnJlcSAgICA9IGdyb3VuZF9uIC8gc3VtKGdyb3VuZF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfZnJlcSAgID0gc2VtaV9hcV9uIC8gc3VtKHNlbWlfYXFfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fZnJlcSAgICA9IHN0cmVhbV9uIC8gc3VtKHN0cmVhbV9uKSAqIDEwMCkgJT4lCiAgZHBseXI6OnNlbGVjdChjKGRpZmZfMkNfY2F0LCBhbGxfZnJlcTpzdHJlYW1fZnJlcSkpICU+JQogICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygizpREdXJhdGlvbiAobW9udGhzKSIsICJBbGwgKCUpIiwgIkFxdWF0aWMgKCUpIiwgIkFyYm9yZWFsICglKSIsICJGb3Nzb3JpYWwgKCUpIiwgIkdyb3VuZC1kd2VsbGluZyAoJSkiLCAiU2VtaS1hcXVhdGljICglKSIsICJTdHJlYW0tZHdlbGxpbmcgKCUpIiksCiAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKSAjIDIgZGVjaW1hbCBwbGFjZXMKYGBgCgoqKioKCiMjIyA0wrBDIFBEU0kgcmlzayB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKClBlcmNlbnQgY2hhbmdlIGluIGRyb3VnaHQgaW50ZW5zaXR5ICjOlFBEU0kpLCBmcmVxdWVuY3kgKM6URnJlcXVlbmN5KSwgYW5kIGR1cmF0aW9uICjOlER1cmF0aW9uKSBieSAyMDgw4oCTMjA5OSAoKyA0wrBDIHNjZW5hcmlvKSByZWxhdGl2ZSB0byBjdXJyZW50IGNsaW1hdGUgKDE5NzDigJMyMDAwKSBpbiBncmlkIGNlbGxzIG9jY3VwaWVkIGJ5IGFudXJhbnMgYW5kIGJ5IGVjb3R5cGUuCgpgYGB7ciBQRFNJIHN1bSA0LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojSW50ZW5zaXR5ClBEU0lfc3BfNEMgJT4lCiAgZHBseXI6OnNlbGVjdChjKGNoYW5nZV80QywgYWxsX2ZyZXE6c3RyZWFtX2ZyZXEpKSAlPiUKICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygizpRQRFNJIiwgIkFsbCAoJSkiLCAiQXF1YXRpYyAoJSkiLCAiQXJib3JlYWwgKCUpIiwgIkZvc3NvcmlhbCAoJSkiLCAiR3JvdW5kLWR3ZWxsaW5nICglKSIsICJTZW1pLWFxdWF0aWMgKCUpIiwgIlN0cmVhbS1kd2VsbGluZyAoJSkiKSwKICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpICMgMiBkZWNpbWFsIHBsYWNlcwoKIyBGcmVxdWVuY3kKZnJlcV80Q19kaWZmX2RmIDwtIGZyZXFfZGlmZl9kZiAlPiUKICBkcGx5cjo6c2VsZWN0KHgsIHksIGRpZmZfNEMpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBjYXNlX3doZW4oCiAgICBkaWZmXzRDID49IDEwIH4gIjEwLTEyIiwgCiAgICBkaWZmXzRDID49IDggJiBkaWZmXzRDIDwgMTAgfiAnOC0xMCcsCiAgICBkaWZmXzRDID49IDYgJiBkaWZmXzRDIDwgOCB+ICc2LTgnLCAgCiAgICBkaWZmXzRDID49IDQgJiBkaWZmXzRDIDwgNiB+ICc0LTYnLCAgCiAgICBkaWZmXzRDID49IDIgJiBkaWZmXzRDIDwgNCB+ICcyLTQnLAogICAgZGlmZl80QyA+PSAxICYgZGlmZl80QyA8IDIgfiAnMS0yJywKICAgIGRpZmZfNEMgPiAwICYgZGlmZl80QyA8IDEgfiAnMC0xJywKICAgIGRpZmZfNEMgPj0gLTEgJiBkaWZmXzRDIDwgMCB+ICctMC0xJywKICAgIGRpZmZfNEMgPj0gLTIgJiBkaWZmXzRDIDwgLTEgfiAnLTEtMicsCiAgICBkaWZmXzRDID49IC00ICYgZGlmZl80QyA8IC0yIH4gJy0yLTQnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBmYWN0b3IoZGlmZl80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnMTAtMTInLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAnMC0xJywgJy0wLTEnLCAnLTEtMicsICctMi00JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKZnJlcV9zcF80Q19kZiA8LSBhbnVyYW5fc3JfZGYgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZnJlcV80Q19kaWZmX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhcXVhdGljX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihhcmJvcmVhbF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZm9zc29yaWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihncm91bmRfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKHNlbWlfYXFfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKHN0cmVhbV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lCiAgZmlsdGVyKGRpZmZfNENfY2F0ICE9ICJOQSIgJiBzcGVjaWVzX24gIT0gIk5BIikKCmRhdGEuZnJhbWUoZnJlcV9zcF80Q19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoZGlmZl80Q19jYXQpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2Uoc3BlY2llc19uICAgPSBsZW5ndGgoc3BlY2llc19uWyFpcy5uYShzcGVjaWVzX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFxdWF0aWNfbiAgID0gbGVuZ3RoKGFxdWF0aWNfblshaXMubmEoYXF1YXRpY19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmJvcmVhbF9uICA9IGxlbmd0aChhcmJvcmVhbF9uWyFpcy5uYShhcmJvcmVhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfbiA9IGxlbmd0aChmb3Nzb3JpYWxfblshaXMubmEoZm9zc29yaWFsX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9uICAgID0gbGVuZ3RoKGdyb3VuZF9uWyFpcy5uYShncm91bmRfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VtaV9hcV9uICAgPSBsZW5ndGgoc2VtaV9hcV9uWyFpcy5uYShzZW1pX2FxX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbV9uICAgID0gbGVuZ3RoKHN0cmVhbV9uWyFpcy5uYShzdHJlYW1fbildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoYWxsX2ZyZXEgICAgICAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGFxdWF0aWNfZnJlcSAgID0gYXF1YXRpY19uIC8gc3VtKGFxdWF0aWNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcmJvcmVhbF9mcmVxICA9IGFyYm9yZWFsX24gLyBzdW0oYXJib3JlYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBmb3Nzb3JpYWxfZnJlcSA9IGZvc3NvcmlhbF9uIC8gc3VtKGZvc3NvcmlhbF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIGdyb3VuZF9mcmVxICAgID0gZ3JvdW5kX24gLyBzdW0oZ3JvdW5kX24pICogMTAwLAogICAgICAgICAgICAgICAgc2VtaV9hcV9mcmVxICAgPSBzZW1pX2FxX24gLyBzdW0oc2VtaV9hcV9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHN0cmVhbV9mcmVxICAgID0gc3RyZWFtX24gLyBzdW0oc3RyZWFtX24pICogMTAwKSAlPiUKICBkcGx5cjo6c2VsZWN0KGMoZGlmZl80Q19jYXQsIGFsbF9mcmVxOnN0cmVhbV9mcmVxKSkgJT4lCiAgIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCLOlEZyZXF1ZW5jeSAobW9udGhzKSIsICJBbGwgKCUpIiwgIkFxdWF0aWMgKCUpIiwgIkFyYm9yZWFsICglKSIsICJGb3Nzb3JpYWwgKCUpIiwgIkdyb3VuZC1kd2VsbGluZyAoJSkiLCAiU2VtaS1hcXVhdGljICglKSIsICJTdHJlYW0tZHdlbGxpbmcgKCUpIiksCiAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKSAjIDIgZGVjaW1hbCBwbGFjZXMKCiMgRHVyYXRpb24KZHVyXzRDX2RpZmZfZGYgPC0gZHVyX2RpZmZfZGYgJT4lCiAgZHBseXI6OnNlbGVjdCh4LCB5LCBkaWZmXzRDKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRpZmZfNENfY2F0ID0gY2FzZV93aGVuKAogICAgZGlmZl80QyA+PSAxMCB+ICI+MTAiLCAKICAgIGRpZmZfNEMgPj0gOCAmIGRpZmZfNEMgPCAxMCB+ICc4LTEwJywKICAgIGRpZmZfNEMgPj0gNiAmIGRpZmZfNEMgPCA4IH4gJzYtOCcsICAKICAgIGRpZmZfNEMgPj0gNCAmIGRpZmZfNEMgPCA2IH4gJzQtNicsICAKICAgIGRpZmZfNEMgPj0gMiAmIGRpZmZfNEMgPCA0IH4gJzItNCcsCiAgICBkaWZmXzRDID49IDEgJiBkaWZmXzRDIDwgMiB+ICcxLTInLAogICAgZGlmZl80QyA+IDAgJiBkaWZmXzRDIDwgMSB+ICcwLTEnLAogICAgZGlmZl80QyA+PSAtMSAmIGRpZmZfNEMgPCAwIH4gJy0wLTEnLAogICAgZGlmZl80QyA+PSAtMiAmIGRpZmZfNEMgPCAtMSB+ICctMS0yJywKICAgIGRpZmZfNEMgPj0gLTQgJiBkaWZmXzRDIDwgLTIgfiAnLTItNCcsCiAgICBkaWZmXzRDID49IC02ICYgZGlmZl80QyA8IC00IH4gJy00LTYnLAogICAgZGlmZl80QyA+PSAtOCAmIGRpZmZfNEMgPCAtNiB+ICctNi04JywKICAgIGRpZmZfNEMgPj0gLTEwICYgZGlmZl80QyA8IC04IH4gJy04LTEwJywgICAKICAgIGRpZmZfNEMgPCAtMTAgfiAnPC0xMCcgCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl80Q19jYXQgPSBmYWN0b3IoZGlmZl80Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjEwJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgJzAtMScsICctMC0xJywgJy0xLTInLCAnLTItNCcsICctNC02JywgJy02LTgnLCAnLTgtMTAnLCAnPC0xMCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkKCmR1cl9zcF80Q19kZiA8LSBhbnVyYW5fc3JfZGYgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oZHVyXzRDX2RpZmZfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFxdWF0aWNfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGFyYm9yZWFsX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUgCiAgZHBseXI6OmZ1bGxfam9pbihmb3Nzb3JpYWxfc3JfZGYsIGJ5ID0gYygieCIgLCJ5IikpICU+JSAKICBkcGx5cjo6ZnVsbF9qb2luKGdyb3VuZF9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc2VtaV9hcV9zcl9kZiwgYnkgPSBjKCJ4IiAsInkiKSkgJT4lIAogIGRwbHlyOjpmdWxsX2pvaW4oc3RyZWFtX3NyX2RmLCBieSA9IGMoIngiICwieSIpKSAlPiUKICBmaWx0ZXIoZGlmZl80Q19jYXQgIT0gIk5BIiAmIHNwZWNpZXNfbiAhPSAiTkEiKQoKZGF0YS5mcmFtZShkdXJfc3BfNENfZGYgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGRpZmZfNENfY2F0KSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiAgID0gbGVuZ3RoKHNwZWNpZXNfblshaXMubmEoc3BlY2llc19uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcXVhdGljX24gICA9IGxlbmd0aChhcXVhdGljX25bIWlzLm5hKGFxdWF0aWNfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJib3JlYWxfbiAgPSBsZW5ndGgoYXJib3JlYWxfblshaXMubmEoYXJib3JlYWxfbildKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9zc29yaWFsX24gPSBsZW5ndGgoZm9zc29yaWFsX25bIWlzLm5hKGZvc3NvcmlhbF9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91bmRfbiAgICA9IGxlbmd0aChncm91bmRfblshaXMubmEoZ3JvdW5kX24pXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbWlfYXFfbiAgID0gbGVuZ3RoKHNlbWlfYXFfblshaXMubmEoc2VtaV9hcV9uKV0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1fbiAgICA9IGxlbmd0aChzdHJlYW1fblshaXMubmEoc3RyZWFtX24pXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGFsbF9mcmVxICAgICAgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBhcXVhdGljX2ZyZXEgICA9IGFxdWF0aWNfbiAvIHN1bShhcXVhdGljX24pICogMTAwLAogICAgICAgICAgICAgICAgYXJib3JlYWxfZnJlcSAgPSBhcmJvcmVhbF9uIC8gc3VtKGFyYm9yZWFsX24pICogMTAwLAogICAgICAgICAgICAgICAgZm9zc29yaWFsX2ZyZXEgPSBmb3Nzb3JpYWxfbiAvIHN1bShmb3Nzb3JpYWxfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBncm91bmRfZnJlcSAgICA9IGdyb3VuZF9uIC8gc3VtKGdyb3VuZF9uKSAqIDEwMCwKICAgICAgICAgICAgICAgIHNlbWlfYXFfZnJlcSAgID0gc2VtaV9hcV9uIC8gc3VtKHNlbWlfYXFfbikgKiAxMDAsCiAgICAgICAgICAgICAgICBzdHJlYW1fZnJlcSAgICA9IHN0cmVhbV9uIC8gc3VtKHN0cmVhbV9uKSAqIDEwMCkgJT4lCiAgZHBseXI6OnNlbGVjdChjKGRpZmZfNENfY2F0LCBhbGxfZnJlcTpzdHJlYW1fZnJlcSkpICU+JQogICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygizpREdXJhdGlvbiAobW9udGhzKSIsICJBbGwgKCUpIiwgIkFxdWF0aWMgKCUpIiwgIkFyYm9yZWFsICglKSIsICJGb3Nzb3JpYWwgKCUpIiwgIkdyb3VuZC1kd2VsbGluZyAoJSkiLCAiU2VtaS1hcXVhdGljICglKSIsICJTdHJlYW0tZHdlbGxpbmcgKCUpIiksCiAgICAgICAgICAgICAgICBkaWdpdHMgPSAyKSAjIDIgZGVjaW1hbCBwbGFjZXMKYGBgCgoqKioKCiMgU3lzdGVtYXRpYyBzZWFyY2ggey19IAoKIyMgRXhjbHVzaW9uIGNyaXRlcmlhIHstfQoKLSBTdHVkaWVzIHdpdGggbGFuZ3VhZ2VzIHRoYXQgd2VyZSBub3QgdHJhbnNsYXRhYmxlIG9uIEdvb2dsZSBUcmFuc2xhdGUuCi0gRGF0YSBmcm9tIGV4cGVyaW1lbnRhbCB0cmVhdG1lbnRzIHN1Y2ggYXMgcGF0aG9nZW4gaW5mZWN0aW9uLCBwb2xsdXRhbnRzIG9yIHBlc3RpY2lkZSBjb250YW1pbmFudHMsIGFuZCBwaGFybWFjb2xvZ2ljYWwgbWFuaXB1bGF0aW9uIChlLmcuLCBhbnRpZGl1cmV0aWMgaG9ybW9uZXMpLgotIERhdGEgcHJlc2VudGVkIGFzIHBlcmNlbnRhZ2UgY2hhbmdlIGluIGJvZHkgd2VpZ2h0IHdpdGhvdXQgdGhlIGluaXRpYWwgd2VpZ2h0LgotIERhdGEgcHJlc2VudCB3aXRoIG5vIHRpbWUgY29tcG9uZW50LiBFLmcuIENoYW5nZSBpbiBib2R5IHdlaWdodCB1bnRpbCAyMCUgb2Ygd2F0ZXIgbG9zcyB3YXMgcmVhY2hlZCAoJSBjaGFuZ2UgaW4gbWFzcykuCi0gU3R1ZGllcyB3aGVyZSB1bml0cyB3ZXJlIG5vdCBwcmVzZW50ZWQuCgojIyBQcmVmZXJyZWQgUmVwb3J0aW5nIEl0ZW1zIGZvciBTeXN0ZW1hdGljIFJldmlld3MgYW5kIE1ldGEtQW5hbHlzZXMgey19CgpUaGUgZm9sbG93aW5nIEJvb2xlYW4gc2VhcmNoIHN0cmluZyBmb3IgV2ViIG9mIFNjaWVuY2UgKFdvUyk6IChmcm9nIE9SIHRvYWQgT1IgYW51clwqKSBBTkQgKHdhdGVyIGxvc3MgT1Igd2F0ZXIgdXB0YWtlIE9SIGV2YXBvcmF0ZVwqIE9SIHNraW4gcmVzaXN0XCogT1IgY3V0YW5lb3VzIGV2YXBvXCopIEFORCAoZGVoeWRyYXRpb24gT1IgZGVzaWNjYXRpb24gT1Igd2F0ZXIgT1Igc29pbCBtb2lzdFwqKSBOT1QgKHRhZHBvbGUgT1IgbGFydmFcKiBPUiBtaWNlIE9SIHJhdCBPUiBwbGFudCwgT1Igc2VlZCBPUiBmaXNoKSBhbmQgZm9yIFNjb3B1czogKFRJVExFLUFCUy1LRVkoZnJvZyBPUiB0b2FkIE9SIGFudXJcKikgIEFORCBUSVRMRS1BQlMtS0VZKHdhdGVyIEFORCBsb3NzIE9SIHdhdGVyIEFORCB1cHRha2UgT1IgZXZhcG9yYXRlXCogT1Igc2tpbiBBTkQgcmVzaXN0XCogT1IgY3V0YW5lb3VzIEFORCBldmFwb1wqKSkgd2VyZSBwZXJmb3JtZWQgb24gdGhlIDIxIEp1bHkgMjAyMiwgcmVzdWx0aW5nIGluIDQ0OSByZWNvcmRzIGZyb20gMTkzOCB0byAyMDIyIGZyb20gdGhlIFdvUywgYW5kIDUxIHJlY29yZHMgZnJvbSAxOTUxIHRvIDIwMjIgZnJvbSBTY29wdXMuIFdlIGV4Y2x1ZGVkIHRvcGljcyByZWxhdGVkIHRvIGNoZW1pc3RyeSwgcGh5c2ljYWwsIG1hdGVyaWFscyBzY2llbmNlLCBtZWRpY2FsLCBnZW9sb2d5LCBmaXNoZXJpZXMsIG9jZWFub2dyYXBoeSwgYW5kIGVuZ2luZWVyaW5nLiBUaXRsZSBhbmQgYWJzdHJhY3Qgc2NyZWVuaW5nIG9mIHRoZSBzeXN0ZW1hdGljIHNlYXJjaCB3YXMgY29uZHVjdGVkIGluIFtSYXl5YW5dKGh0dHBzOi8vd3d3LnJheXlhbi5haS8pIFtAT3V6emFuaTIwMTZdLiBGb3J3YXJkIGFuZCBiYWNrd2FyZCBzZWFyY2hlcyB3ZXJlIGFsc28gY29uZHVjdGVkIG9uIEdvb2dsZSBTY2hvbGFyIHVudGlsIHRoZSAxNXRoIEF1Z3VzdCAyMDIyICgqKkZpZy4gUzEqKikgZm9yIGFkZGl0aW9uYWwgcGFwZXJzLCBhbmQgd2UgYWxzbyBzZWFyY2hlZCBmb3IgcGFwZXJzIGZyb20gQEZlZGVyMTk5MiwgQExpbGx5d2hpdGUyMDA2LCBhbmQgQEhpbGxtYW4yMDA5LiBMYXN0bHksIGFkZGl0aW9uYWwgc3R1ZGllcyAoKm4qID0gMykgd2VyZSBwcm92aWRlZCBieSB0aGUgU3RlbGxlbmJvc2NoIFVuaXZlcnNpdHkgbGlicmFyaWFuIChzZWFyY2hlZCAxc3QgRmVicnVhcnkgMjAyMykuCgohW10oRmlnIFMzIC0gUFJJU01BIGRpYWdyYW0ucG5nKQoKKipGaWcuIFMzLioqIFBSSVNNQSBmbG93IGRpYWdyYW0gZm9yIHRoZSBzeXN0ZW1hdGljIGRhdGEtY29sbGVjdGlvbiBwcm9jZXNzLiAqbiogPSBudW1iZXIgb2YgcGFwZXJzIHJlbWFpbmluZyBhZnRlciBlYWNoIHN0YWdlIG9mIHNlbGVjdGlvbi4gKmsqIGlzIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zL3JlY29yZHMsIGFuZCAqbiogaW4gdGhlIGxhc3Qgcm93IGlzIG51bWJlciBvZiBzcGVjaWVzIGFmdGVyIHByb2Nlc3NpbmcgZGF0YS4KCiMjIyBEZWZpbml0aW9ucyB7LX0KCldlIG5vdGUsIHRoYXQgIndhdGVyLXByb29mIiBpcyBhIHN1YmplY3RpdmUgdGVybSwgYW5kIHRoZSBtZWNoYW5pc20gaXMgb25seSB3ZWxsIHVuZGVyc3Rvb2QgZm9yIHRoZSAqUGh5bGxvbWVkdXNhKiBnZW51cyB3aXRoIHRoZSBwcmVzZW5jZSBvZiB3YXh5IHNlY3JldGlvbiBvZiBjdXRhbmVvdXMgbGlwaWRzLCBhbmQgdGhlIHN0ZXJlb3R5cGljYWwgd2lwaW5nIGJlaGF2aW91ciBbQEJsYXlsb2NrMTk3NjsgQEdvbWV6MjAwNl0uIE90aGVyIGFyYm9yZWFsIHNwZWNpZXMgc2hvdyBkcnkgbXVjdXMgZmlsbSBvbiB0aGUgc2tpbiBvciB0aGUgcHJlc2VuY2Ugb2YgY3V0YW5lb3VzIHN1cmZhY2UgZmx1aWQgdGhhdCBtYXkgY29udHJpYnV0ZSB0byBoaWdoIHNraW4gcmVzaXN0YW5jZSBbQEtvYmVsdDE5ODZdLiBXZSBsYWJlbGxlZCBmcm9ncyBhcyAid2F0ZXItcHJvb2YiIGJhc2VkIG9uIGVhY2ggc3R1ZHkncyBkZWZpbml0aW9uLCBpLmUuLCBpZiB0aGUgYXV0aG9ycyBkZXNjcmliZSB0aGUgc3BlY2llcyBhcyAid2F0ZXItcHJvb2YiLiBIb3dldmVyLCBub3QgYWxsICJ3YXRlci1wcm9vZiIgZnJvZ3MgZXhjcmV0ZSB3YXRlci1wcm9vZiBzZWNyZXRpb25zIHRocm91Z2hvdXQgdGhlIHllYXIsIGFuZCBtYXkgb25seSBzaG93IHRoaXMgYWRhcHRhdGlvbiBkdXJpbmcgY2VydGFpbiBwZXJpb2RzIHN1Y2ggYXMgdGhlIGRyeSBzZWFzb24gKFIuIFAuIEJvdm8sIHBlcnMuIGNvbW0uKS4gCgpBbm90aGVyIHBvc3QtaG9jIGRlZmluaXRpb24gZm9yIGNsYXNzaWZ5aW5nIHdhdGVyLXByb29mIGlzIHdoZXRoZXIgdGhlIHNraW4gcmVzaXN0YW5jZSBpcyBhYm92ZSBhIGNlcnRhaW4gdGhyZXNob2xkLiBASGlsbG1hbjIwMDkgZGVmaW5lZCBhbnVyYW5zIGFzIG1vZGVyYXRlbHkgd2F0ZXItcHJvb2Ygd2l0aCBza2luIHJlc2lzdGFuY2UgYmV0d2VlbiAyIHRvIDIwIHMgY21eLTFeLCBhbmQgaGlnaGx5IHdhdGVyLXByb29mIHdpdGggc2tpbiByZXNpc3RhbmNlID4yMCBzIGNtXi0xXi4gSG93ZXZlciwgZXZlbiB3aXRoaW4gc3R1ZGllcywgdGhlIHNhbWUgc3BlY2llcyB3aWxsIHNob3cgZGlmZmVyZW50IHNraW4gcmVzaXN0YW5jZSBkZXBlbmRpbmcgb24gdGhlIGVudmlyb25tZW50YWwgZXhwb3N1cmUuIGUuZy4gbG93ZXIgc2tpbiByZXNpc3RhbmNlIGF0IGhpZ2hlciB0ZW1wZXJhdHVyZSBbQEJ1dHRlbWVyMjAwM10uIFdlIGluY2x1ZGVkIGJvdGggZGVmaW5pdGlvbnMgaW4gdGhlIHJhdyBkYXRhIGZpbGUsIGJ1dCB3ZSB1c2VkIHRoZSBwcmlvciBkZWZpbml0aW9uIGZvciBhbmFseXNpcy4KCkVXTCBtZWFzdXJlbWVudHMgbGFiZWxsZWQgd2l0aCAiY29jb29uIiBpcyBzdHJhaWdodC1mb3J3YXJkLiBDb2Nvb24gaXMgdGhlIHByZXNlbmNlIG9mIGFjY3VtdWxhdGVkIGVwaWRlcm1hbCBsYXllcnMgaW4gYWVzdGl2YXRpbmcgYW51cmFucy4gRVdMIG1lYXN1cmVtZW50cyBsYWJlbGxlZCB3aXRoICJob2xsb3ciIHdlcmUgY29uZHVjdGVkIHdpdGggZnJvZ3MgaW4gYW4gYXJ0aWZpY2lhbCBob2xsb3cgc2hlbHRlciBwcm90ZWN0aW5nIHRoZSBmcm9nIGZyb20gdGhlIGV4cG9zZWQgYWlyLgoKQW51cmFucyBjYW4gYWxzbyBjaGFuZ2UgRVdMIGFjcm9zcyB0aGUgbWVhc3VyZW1lbnQgcGVyaW9kIChpLmUuIGRlY3JlYXNlIGluIEVXTCBhcyB0aGV5IGJlY29tZSBtb3JlIGRlaHlkcmF0ZWQpLiBIb3dldmVyLCBtb3N0IHN0dWRpZXMgZWl0aGVyIHRvb2sgYW4gYXZlcmFnZSB2YWx1ZSBvdmVyIHRoZSBleHBlcmltZW50IGR1cmF0aW9uLCBvciBwcmVzZW50ZWQgdGhlIGZpcnN0IGhvdXIgb2YgbWVhc3VyZW1lbnRzLiBXaGVuIHN0dWRpZXMgcHJvdmlkZWQgY2hhbmdlIGluIEVXTCBhdCBkaWZmZXJlbnQgdGltZSBwb2ludHMsIHdlIHRvb2sgdGhlIGZpcnN0IGhvdXIgRVdMIG1lYXN1cmVtZW50cy4gTm90ZSwgYWxtb3N0IGFsbCBhbmltYWxzIHdlcmUgY29uc2lkZXJlZCBmdWxseSBoeWRyYXRlZCBkdXJpbmcgdGhlIHN0YXJ0IG9mIHRoZSBFV0wgZXhwZXJpbWVudCwgd2hlcmUgdGhleSB3ZXJlIHN1Ym1lcnNlZCBvciBwcm92aWRlZCB3YXRlciBwcmlvciB0byB0aGUgRVdMIGV4cGVyaW1lbnRzLiAKCiMjIFVucHVibGlzaGVkIGRhdGEgey19CgpBZGRpdGlvbmFsIEVXTCwgJHJfaSQsIGFuZCBXVSBkYXRhIHdlcmUgb2J0YWluZWQgZnJvbSB1bnB1Ymxpc2hlZCBzb3VyY2VzLiBUaGUgKkF0ZWxvcHVzIGNhcnJpa2VyaSogZGF0YSBpcyBhdmFpbGFibGUgb24gYW4gb25saW5lIHJlcG9zaXRvcnkgKFtTb2xhbm8gJiBBbGJlcnQsIDIwMDBdKGh0dHBzOi8vZGF0YS5tZW5kZWxleS5jb20vZGF0YXNldHMvNGM1bmtwcnpjeS8xKSksIGFuZCB0aGUgKlRob3JvcGEgbWlsaWFyaXMqIGRhdGEgY2FuIGJlIG9idGFpbmVkIGZyb20gQy4gTmF2YXMgKG5hdmFzQHVzcC5icikgdXBvbiByZXF1ZXN0LgoKQnJpZWZseSwgdGhlIG1ldGhvZCBmb3IgKkF0ZWxvcHVzIGNhcnJpa2VyaSogaXMgZGVzY3JpYmVkIGJlbG93OgoKMTUgKkF0ZWxvcHVzIGNhcnJpa2VyaSogd2VyZSBjb2xsZWN0ZWQgbmVhciB0aGUgYmFzaW4gb2YgUGljbyBDcmlzdMOyYmFsIENvbMOybiAoMTDCsDU0JzA1LjgiTiA3M8KwNTUnMDAuNyJXKSBhbmQgYnJvdWdodCBiYWNrIHRvIHRoZSBVbml2ZXJzaWRhZCBkZWwgTWFnZGFsZW5hIGNhbXB1cy4gVG8gZXN0aW1hdGUgZXZhcG9yYXRpdmUgd2F0ZXIgbG9zcywgZnVsbHkgaHlkcmF0ZWQgaW5kaXZpZHVhbHMgd2VyZSBicmllZmx5IGRyaWVkIHdpdGggYWJzb3JiZW50IHBhcGVyIGFuZCB0aGUgdXJpbmUgd2FzIHJlbW92ZWQgYnkgbGlnaHRseSBwcmVzc2luZyB0aGVpciBhYmRvbWVuIGFuZCB3ZWlnaGVkIHRvIG9idGFpbiB0aGUgaW5pdGlhbCB3ZWlnaHQuIEVhY2ggaW5kaXZpZHVhbCB3YXMgcGxhY2VkIGluIGEgd2luZCB0dW5uZWwgYXQgMi40IHMgY21eLTFeLCBhbmQgd2VpZ2hlZCBldmVyeSBmaXZlIG1pbnV0ZSB1bnRpbCBpbmRpdmlkdWFscyByZWFjaGVkIDcwLTY1JSBvZiB0aGVpciBpbml0aWFsIHdlaWdodCBbQFRpdG9uMjAxMF0uIFRoZSByYXRlIG9mIEVXTCB3YXMgY2FsY3VsYXRlZCBmcm9tIHRoZSB2YWx1ZSBvZiB0aGUgcmVncmVzc2lvbiBvZiB0aGUgd2VpZ2h0IGxvc3Qgb3ZlciB0aW1lIGFuZCBleHByZXNzZWQgaW4gbWcgbWluXi0xXi4gRVdMIGNvcnJlY3RlZCBmb3Igc3VyZmFjZSBhcmVhIHdhcyBjYWxjdWxhdGVkIGJ5IGRpdmlkaW5nIGJ5IDIvMyBvZiB0aGUgdG90YWwgc3VyZmFjZSBhcmVhIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSByZWdpb24gb2YgdGhlIGJvZHkgaW4gY29udGFjdCB3aXRoIHRoZSBhaXIgZmxvdyAobWcgY21eLTJeIG1pbl4tMV4pIFtAV2l0aGVyczE5ODI7IEBUaXRvbjIwMTA7IEBUaXRvbjIwMTVdLiAKClRvIGVzdGltYXRlIHJhdGUgb2YgV1UsIEluZGl2aWR1YWxzIHdoZXJlIHBsYWNlZCBpbiBjb250YWluZXJzIHdpdGggYWJzb3JiZW50IHRvd2VscyBtb2lzdGVuZWQgd2l0aCBlbm91Z2ggd2F0ZXIgdG8gY292ZXIgdGhlIHZlbnRyYWwgcmVnaW9uIGFmdGVyIHRoZSBFV0wgZXhwZXJpbWVudC4gVGhlIGluZGl2aWR1YWxzIHdlcmUgZHJpZWQgYW5kIHdlaWdoZWQgZXZlcnkgZm91ciBtaW51dGVzIGZvciBzaXggY29uc2VjdXRpdmUgdGltZXMgW0BUaXRvbjIwMTA7IEBBbmRlcnNvbjIwMTddLiBUaGUgV1UgcmF0ZSBwZXIgYXJlYSB3YXMgY2FsY3VsYXRlZCBmcm9tIHRoZSB2YWx1ZSBvZiB0aGUgcmVncmVzc2lvbiBvZiB0aGUgYm9keSB3ZWlnaHQgZ2FpbmVkIGFzIGEgZnVuY3Rpb24gb2YgdGltZSAobWcgbWluXi0xXiksIGFuZCBpbiB0dXJuIGRpdmlkZWQgYnkgMS8zIG9mIHRoZSB0b3RhbCBzdXJmYWNlIGFyZWEgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgdmVudHJhbCBhcmVhIGluIGNvbnRhY3Qgd2l0aCB3YXRlciBkdXJpbmcgYWJzb3JwdGlvbiwgdGhlIHZhbHVlcyB3ZXJlIGV4cHJlc3NlZCBpbiB1bml0cyBvZiBtZyBjbV4tMl4gbWluXi0xXi4gQWxsIGV4cGVyaW1lbnRzIHdlcmUgY29uZHVjdGVkIGF0IGFuIGF2ZXJhZ2UgYWlyIHRlbXBlcmF0dXJlIG9mIDI1LjU1IMKxIDAuMjjCsEMuIFRoZSByZWxhdGl2ZSBodW1pZGl0eSB3YXMgbm90IG1lYXN1cmVkIGJ1dCBhcHByb3hpbWF0ZWQgYmFzZWQgb24gdGhlIGxvY2F0aW9uIGFuZCB0aW1lIG9mIHRoZSBleHBlcmltZW50IChSLiBTb2xhbm8gcGVycy4gY29tbS4pCgpUaGUgbWV0aG9kIGZvciAqVGhvcm9wYSBtaWxpYXJpcyogaXMgZGVzY3JpYmVkIGJlbG93OgoKMTQgKlRob3JvcGEgbWlsaWFyaXMqIHdlcmUgY29sbGVjdGVkIGFyb3VuZCBVYmF0dWJhIChhcHByb3hpbWF0ZSBsb2NhdGlvbiAyM8KwMjbigLIxM+KAs1MgNDXCsDA04oCyMDjigLNXKSwgYW5kIDE1IGluZGl2aWR1YWxzIHdlcmUgY29sbGVjdGVkIGluIHRoZSBTZXJyYSBkbyBNYXIgU3RhdGUgUGFyaywgUGljaW5ndWFiYSBOdWNsZXVzIChhcHByb3hpbWF0ZSBsb2NhdGlvbiAyM8KwMjfigJk1MOKAnVMgdG8gMjPCsDE14oCZMDDigJ1TIGFuZCA0NcKwMTXigJkwMOKAnVcgdG8gNDTCsDQz4oCZMzDigJ1XKS4gQW5pbWFscyB3ZXJlIGJyb3VnaHQgYmFjayB0byB0aGUgVW5pdmVyc2l0eSBvZiBTw6NvIFBhdWxvIGNhbXB1cyBhbmQga2VwdCBpbmRpdmlkdWFsbHkgaW4gcGxhc3RpYyBlbmNsb3N1cmVzICgxNyB4IDE4IHggMTA3IGNtKSBmb3IgNS03IGRheXMgcHJpb3IgdG8gZXN0aW1hdGluZyBFV0wuIEFuaW1hbHMgd2VyZSBmZWQgY2FwdGl2ZSBjb2Nrcm9hY2hlcyAoKk5hdXBob2V0YSBjaW7DqXJlYSopIHR3aWNlIGEgd2VlayBhbmQgd2VyZSBwcm92aWRlZCBmcmVzaCB3YXRlciBhZCBsaWJpdHVtICh0YXAgd2F0ZXIpIGluIGEgcGxhc3RpYyBjdXAuIFRvIGVzdGltYXRlIEVXTCwgZnVsbHkgaHlkcmF0ZWQgaW5kaXZpZHVhbHMgd2VyZSBicmllZmx5IGRyaWVkIHdpdGggYWJzb3JiZW50IHBhcGVyIGFuZCB0aGUgdXJpbmUgd2FzIHJlbW92ZWQgYnkgbGlnaHRseSBwcmVzc2luZyB0aGVpciBhYmRvbWVuIGFuZCB3ZWlnaGVkIHRvIG9idGFpbiB0aGUgaW5pdGlhbCB3ZWlnaHQuIEVhY2ggaW5kaXZpZHVhbCB3YXMgcGxhY2VkIGluIGEgd2luZCB0dW5uZWwgYXQgMjM1IHMgY21eLTFeLCBhbmQgd2VpZ2hlZCBldmVyeSBmaXZlIG1pbnV0ZSB1bnRpbCBpbmRpdmlkdWFscyByZWFjaGVkIDkwJSBvZiB0aGVpciBpbml0aWFsIHdlaWdodCBvciB0aGUgYW5pbWFsIGRpZCBub3QgcmVnYWluIHBvc3R1cmUgd2hlbiB0dXJuZWQgb3Zlci4gRWFjaCBpbmRpdmlkdWFsIG1lYXN1cmVtZW50IHdhcyByZXBsaWNhdGVkIHR3aWNlIG92ZXIgdGhlICgzIGRheXMgaW4gYmV0d2VlbiBtZWFzdXJlbWVudHMpIGFuZCBhdmVyYWdlZC4gVGhlIHJhdGUgb2YgRVdMIGZyb20gdGhlIGF2ZXJhZ2UgdmFsdWVzIHdhcyBjYWxjdWxhdGVkIGFuZCBwcmVzZW50ZWQgYXMgaW4gbWcgaF4tMV4uIEVXTCBjb3JyZWN0ZWQgZm9yIHN1cmZhY2UgYXJlYSB3YXMgY2FsY3VsYXRlZCBieSBkaXZpZGluZyBieSAyLzMgb2YgdGhlIHRvdGFsIHN1cmZhY2UgYXJlYSB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgcmVnaW9uIG9mIHRoZSBib2R5IGluIGNvbnRhY3Qgd2l0aCB0aGUgYWlyIGZsb3cgKG1nIGNtXi0yXiBtaW5eLTFeKS4gVGhlIGV4cGVyaW1lbnQgd2FzIGNvbmR1Y3RlZCBhdCBhbiBhaXIgdGVtcGVyYXR1cmUgYmV0d2VlbiAyMi0yNcKwQyBhdCBhIHJlbGF0aXZlIGh1bWlkaXR5IG9mIDUwLTYwJS4KCkRhdGEgcHJvdmlkZWQgYnkgUi4gUGFyZWxsaSBCb3ZvIChycGJvdm9AZ21haWwuY29tKSB3YXMgb3JpZ2luYWxseSB1c2VkIGZvciBhIHNlcGFyYXRlIHBhcGVyIHdoaWNoIGlzIGN1cnJlbnRseSBpbiBkZXZlbG9wbWVudC4gSG93ZXZlciwgaGUgaGFzIGtpbmRseSBvZmZlcmVkIHRvIHByb3ZpZGUgdGhlIGRhdGEgZm9yIHRoaXMgc3R1ZHkgcHJlLXN1Ym1pc3Npb24uIFRoZSBzcGVjaWVzIHRoYXQgd2VyZSBjb2xsZWN0ZWQgYnkgUi4gUGFyZWxsaSBCb3ZvIGFyZSBwcm92aWRlZCBiZWxvdzoKCi0gKkFkZW5vbWVyYSBtYXJtb3JhdGEqCi0gKkFtZWVyZWdhIGZsYXZvcGljdGEqCi0gKkFwbGFzdG9kaXNjdXMgbGV1Y29weWdpdXMqCi0gKkJvYW5hIHBhcmRhbGlzKgotICpCb2FuYSByYW5pY2VwcyoKLSAqQm9rZXJtYW5ub2h5bGEgYWx2YXJlbmdhaSoKLSAqQm9rZXJtYW5ub2h5bGEgY2lyY3VtZGF0YSoKLSAqQm9rZXJtYW5ub2h5bGEgc2F4aWNvbGEqCi0gKkJyYWNoeWNlcGhhbHVzIHBpdGFuZ2EqCi0gKkRlbmRyb3Bzb3BodXMgbWljcm9wcyoKLSAqRGVuZHJvcHNvcGh1cyBzYW5ib3JuaSoKLSAqRGVybWF0b25vdHVzIG11ZWxsZXJpKgotICpFbGFjaGlzdG9jbGVpcyBjZXNhcmlpKgotICpIYWRkYWR1cyBiaW5vdGF0dXMqCi0gKklzY2hub2NuZW1hIGd1ZW50aGVyaSoKLSAqSXNjaG5vY25lbWEgcGFydmEqCi0gKkxlcHRvZGFjdHlsdXMgZnVzY3VzKgotICpMZXB0b2RhY3R5bHVzIHN5cGhheCoKLSAqT2RvbnRvcGhyeW51cyBhbWVyaWNhbnVzKgotICpQaHlsbG9tZWR1c2EgbWVnYWNlcGhhbGEqCi0gKlBoeXNhbGFlbXVzIGF0bGFudGljdXMqCi0gKlBoeXNhbGFlbXVzIG9sZmVyc2lpKgotICpQaXRoZWNvcHVzIGF6dXJlYWUqCi0gKlByb2NlcmF0b3BocnlzIGFwcGVuZGljdWxhdGEqCi0gKlByb2NlcmF0b3BocnlzIGN1cnVydSoKLSAqUmhpbmVsbGEgZGlwdHljaGEqCi0gKlJoaW5lbGxhIG9ybmF0YSoKLSAqUmhpbmVsbGEgcnViZXNjZW5zKgotICpTY2luYXggZnVzY292YXJpdXMqCi0gKlRyYWNoeWNlcGhhbHVzIG1lc29waGFldXMqCgpBZHVsdHMgd2VyZSBjb2xsZWN0ZWQgYWxvbmcgZWxldmF0aW9uYWwgZ3JhZGllbnRzIGZyb20gc2VhIGxldmVsIHRvIDEsNjAwIG0gYS5zLmwgaW4gQnJhemls4oCZcyBBdGxhbnRpYyBGb3Jlc3QgYW5kIENlcnJhZG8gZHVyaW5nIHdhcm0vd2V0IHNlYXNvbnMgKFNlcHRlbWJlciB0byBGZWJydWFyeSBvZiAyMDEx4oCTMjAxNykuIEFuaW1hbHMgd2VyZSB0cmFuc3BvcnRlZCB0byB0aGUgbGFib3JhdG9yeSAoNjEzIG06IC0yMi4zOTczMzHCsCBTLCA0Ny41NDc3OTnCsCBXKS4gQWxsIGFuaW1hbHMgd2VyZSBrZXB0IGluZGl2aWR1YWxseSBpbiBwbGFzdGljIHRlcnJhcmlhLCB3aXRoIHNoZWx0ZXIgYW5kIHRhcCB3YXRlciBhZCBsaWJpdHVtLCB1bmRlciBuYXR1cmFsIHRoZXJtYWwvaHVtaWRpdHkgcmVnaW1lcyAoZGFpbHkgdGVtcGVyYXR1cmUgcmFuZ2Ugb2YgMjLigJMyNyDCsEMsIGFpciBodW1pZGl0eSBvZiA0NeKAkzY1JSkgYW5kIHBob3RvcGVyaW9kIChsaWdodC9kYXJrIGN5Y2xlcyAxMy41OjEwLjUpLgoKTWVhc3VyZW1lbnRzIHdlcmUgdGFrZW4gb25jZSBmb3IgZWFjaCBpbmRpdmlkdWFsLCBpbiB0aGUgZm9sbG93aW5nIHNlcXVlbmNlOiBFV0wgYW5kIFdVIHdpdGhpbiAzLTUgZGF5cyBhZnRlciBmaWVsZCBjb2xsZWN0aW9uLiBBbmltYWxzIHdlcmUgbm90IGZlZCBhcyB0aGUgbWVhc3VyZW1lbnRzIHdlcmUgdGFrZW4gaW4gYSBmYXN0ZWQgc3RhdGUuIEJlZm9yZSBhbmQgYWZ0ZXIgYW55IGV4cGVyaW1lbnRhbCBydW4sIGFuaW1hbHMgd2VyZSBjaGVja2VkIGZvciBtb3RvciBjb29yZGluYXRpb24sIHNraW4gY29sb3IsIHBvc3R1cmUsIGFuZCByZXNwb25zaXZlbmVzcy4gV2hlbiBpbmRpdmlkdWFscyBmYWlsZWQgdGhlc2UgY2hlY2tzLCB0aGV5IHdlcmUgbm90IGluY2x1ZGUgaW4gdGhlIGRhdGFzZXQgYW5kIHN1YnNlcXVlbnQgYW5hbHlzZXMuCgpFV0wgYW5kIFdVIGV4cGVyaW1lbnRzIHdlcmUgY29uZHVjdGVkIGZvbGxvd2luZyBAQW5kZXJzb24yMDE3LCBAR291dmVpYTIwMTksIGFuZCBAQm92bzIwMjMuIEJyaWVmbHksIGFuaW1hbHPigJkgdGVtcGVyYXR1cmUgYW5kIGh5ZHJhdGlvbiBzdGF0ZSB3ZXJlIHN0YW5kYXJkaXNlZCBiZWZvcmUgdGhlIHRyaWFscyBieSBob2xkaW5nIGVhY2ggYW1waGliaWFuIGluIGluZGl2aWR1YWwgUFZDIGNvbnRhaW5lcnMsIGZpbGxlZCB3aXRoIDAuNSBjbSAoYm9keSBzaXplcyA8IDUgZykgb3IgMSBjbSBvZiB3YXRlciAoYm9keSBzaXplcyA+IDUgZyksIGFuZCBwbGFjZWQgaW5zaWRlIGEgY2xpbWF0ZS1jb250cm9sbGVkIGluY3ViYXRvciAoMTIyRkMgbW9kZWwgLSBFbGV0cm9sYWIpIGF0IDI1IMKwQyBmb3IgMSBoLiBUbyBvYnRhaW4gdGhlIGluaXRpYWwgc3RhbmRhcmRpc2VkIGJvZHkgbWFzcyAoMTAwJSBoeWRyYXRlZCksIGZyb2dzIHdlcmUgZ2VudGx5IGRyaWVkIHdpdGggYWJzb3JiZW50IHBhcGVyIGFuZCB0aGVpciBhYmRvbWVuIHdlcmUgbGlnaHRseSBwcmVzc2VkIHRvIHJlbW92ZSB1cmluZSBmcm9tIHRoZWlyIHVyaW5hcnkgYmxhZGRlci4gVGhlbiwgZnJvZ3Mgd2VyZSBpbmRpdmlkdWFsbHkgcGxhY2VkIGluIFBWQyBjb250YWluZXJzICgxLDAwMCBtbCkgYW5kIEVXTCByYXRlcyB3ZXJlIG1lYXN1cmVkIGluIGEgdHlwaWNhbCBvcGVuLWZsb3cgc3lzdGVtIGF0IDI1IMKwQywgY29udGFpbmluZyBhIG1hc3MgZmxvdyBtZXRlciAoU1MtMyBTdWJzYW1wbGVyLCBTYWJsZSBTeXN0ZW1zKSBzdXBwbHlpbmcgYSBzdGFibGUgYWlyZmxvdyBhdCAyMS42NiBjbV4zXiBzXi0xXiAoMSwzMDAgbWwgbWluXi0xXiksIGEgUkgvRGV3cG9pbnQgQ29udHJvbGxlciAoREctNCwgU2FibGUgU3lzdGVtcykgc3RhbmRhcmRpemluZyB0aGUgaW5jdXJyZW50IHJlbGF0aXZlIGh1bWlkaXR5IGF0IDMwJSwgYW5kIGEgd2F0ZXIgdmFwb3IgYW5hbHl6ZXIgKFJILTMwMCBSSC9EZXdwb2ludCBBbmFseXplciwgU2FibGUgU3lzdGVtcykgcXVhbnRpZnlpbmcgaW5jdXJyZW50IGFuZCBleGN1cnJlbnQgYWlyLiBBbGwgZXF1aXBtZW50IHdhcyBpbnRlcmZhY2VkIHRvIGEgY29tcHV0ZXIgYnkgYW4gYW5hbG9nL2RpZ2l0YWwgdW5pdCAoVUkyLCBTYWJsZSBTeXN0ZW1zKSB0byByZWNvcmQgY2hhbmdlcyBpbiBhaXJmbG93IGFuZCB3YXRlciB2YXBvciBkZW5zaXR5IChXVkQpIGV2ZXJ5IDEuMCBzZWNvbmQuIFNraW4gYm9keSB0ZW1wZXJhdHVyZXMgd2VyZSB0YWtlbiBhdCB0aGUgZW5kIG9mIHRoZSBleHBlcmltZW50cywgdHlwaWNhbGx5IDMwLTQwIG1pbiBmb3IgZnJvZ3MgPCA1IGcgYW5kIDYwIG1pbiBmb3IgZnJvZ3MgPiA1IGcsIGZvciBxdWFudGlmaWNhdGlvbiBvZiB0aGUgV1ZEIGF0IHNhdHVyYXRpb24gYXQgdGhlIGV2YXBvcmF0aW5nIChza2luKSBzdXJmYWNlLiBUbyBxdWFudGlmeSB0aGUgRVdMIHJhdGVzLCB0aGUgd2F0ZXIgdmFwb3IgZGVuc2l0eSBkZWZpY2l0IHdhcyBjYWxjdWxhdGVkIGJ5IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gYW4gZW1wdHkgY29udGFpbmVyIGFuZCBvbmUgY29udGFpbmluZyB0aGUgYW5pbWFsIChTcG90aWxhIGFuZCBCZXJtYW4gMTk3NikuIFRoZW4sIHRvdGFsIHRyYW5zZXBpdGhlbGlhbCBFV0wgd2FzIGNvcnJlY3RlZCBmb3IgdW5pdCBhcmVhIG9mIGV4cG9zZWQgc2tpbiBzdXJmYWNlICgyLzMgb2YgdGhlIHRvdGFsIHN1cmZhY2U7IEBNY0NsYW5haGFuMTk2OSkgYW5kIGV4cHJlc3NlZCBhcyBtYXNzIG9mIHdhdGVyIHBlciBleHBvc2VkIHN1cmZhY2UgYXJlYSBwZXIgdGltZSAoZS5nLiDOvGcgSH4yfk8gY21e4oiSMl4gc17iiJIxXikuIFRvIG1pbmltaXplIHRoZSBhbmltYWzigJlzIGFjdGl2aXR5IGR1cmluZyBFV0wgbWVhc3VyZW1lbnRzLCBleHBlcmltZW50cyB3ZXJlIHBlcmZvcm1lZCBkdXJpbmcgdGhlIGRheSAob3Bwb3NpdGUgdG8gdGhlaXIgbmF0dXJhbCBhY3RpdmUgcGVyaW9kKSB3aXRoIGNoYW1iZXJzIGluIHRoZSBkYXJrLiBUbyBkZXRlY3QgYW55IHNpZ25pZmljYW50IGNoYW5nZXMgaW4gYmVoYXZpb3IgYW5kIHBvc3R1cmUgdGhhdCBjb3VsZCBhZmZlY3QgdGhlIHJlY29yZHMsIGluZGl2aWR1YWxzIHdlcmUgb2Z0ZW4gdmlzdWFsbHkgaW5zcGVjdGVkIGR1cmluZyB0cmlhbHMuIERhdGEgd2VyZSBkaXNjYXJkZWQgaWYgYW4gYW5pbWFsIHVyaW5hdGVkIGR1cmluZyB0aGUgZXhwZXJpbWVudC4KCkltbWVkaWF0ZWx5IGFmdGVyIHRoZSBFV0wgdHJpYWxzLCB3aGVyZSBhbmltYWxzIHVzdWFsbHkgbG9zdCA5OC03MCAlIG9mIHRoZWlyIGluaXRpYWwgYm9keSBtYXNzZXMgKHNlZSBkYXRhc2V0KSwgZWFjaCBpbmRpdmlkdWFsIHdhcyBwbGFjZWQgaW4gYSBjb250YWluZXIgKGEgUGV0cmkgZGlzaCBmb3IgYm9keSBzaXplcyBzbWFsbGVyIHRoYW4gNSBnLCBvciBhIGNpcmN1bGFyIFBWQyBjb250YWluZXIgZm9yIGJvZHkgc2l6ZXMgbGFyZ2VyIHRoYW4gNSBnKSBmaWxsZWQgd2l0aCB0YXAgd2F0ZXIgYXQgYSBkZXB0aCBzdWZmaWNpZW50IHRvIGNvdmVyIHRoZWlyIHZlbnRyYWwgcmVnaW9uLiBBbmltYWxzIHdlcmUgdGFrZW4gZnJvbSB0aGUgY29udGFpbmVyIGFuZCBjYXJlZnVsbHkgYmxvdHRlZCB3aXRoIHBhcGVyIHRpc3N1ZSBhbmQgd2VpZ2hlZCAowrEgMC4wMDAxIGcgb3IgMC4wMSBnKSBldmVyeSAyIG1pbnV0ZXMgZm9yIHNpeCBjb25zZWN1dGl2ZSB0aW1lcyBpbiBhIHJvb20gYXQgMjUgwrBDLiBXVSByYXRlcyB3ZXJlIGNhbGN1bGF0ZWQgZnJvbSB0aGUgbGluZWFyIHJlZ3Jlc3Npb24gYmV0d2VlbiBib2R5IG1hc3MgaW5jcmVtZW50cyBhZ2FpbnN0IHRpbWUuIFRoZW4sIHVzaW5nIHRoZSBlc3RpbWF0ZWQgc3VyZmFjZSBhcmVhIGluIGNvbnRhY3Qgd2l0aCB3YXRlciAoMS8zIG9mIHRoZSB0b3RhbCBzdXJmYWNlLCBATWNDbGFuYWhhbjE5NjkpLCB0aGUgV1UgcmF0ZSB3YXMgY2FsY3VsYXRlZCBhbmQgZXhwcmVzc2VkIHBlciB1bml0IGFyZWEgKGUuZy4gzrxnIEh+Mn5PIGNtXuKIkjJeIHNe4oiSMV4pLgoKRGF0YSBmb3IgKkJyZXZpY2VwcyBtb250YW51cyogcHJvdmlkZWQgYnkgUy4gQ2x1c2VsbGEtVHJ1bGxhcyAoc2N0MzMzQHN1bi5hYy56YSkgd2lsbCBiZSB1c2VkIGZvciBhIG1hbnVzY3JpcHQgdGhhdCBpcyBjdXJyZW50bHkgaW4gc3VibWlzc2lvbi4gSG93ZXZlciwgc2hlIGhhcyBraW5kbHkgb2ZmZXJlZCB0byBwcm92aWRlIHRoZSBkYXRhIGZvciB0aGlzIHN0dWR5IHByZS1zdWJtaXNzaW9uLgoKVGhlIHJhdyBkYXRhLCBpbmNsdWRpbmcgY29sbGVjdGlvbiBzaXRlcywgYXJlIHByb3ZpZGVkIG9uIFtHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9uaWNob2xhc3d1bnovZ2xvYmFsLWZyb2ctZHJvdWdodC90cmVlL21haW4vZGF0YSkuCgoqKioKCiMjIENhbGN1bGF0aW9ucyBhbmQgY29udmVyc2lvbnMgey19CgojIyMgRXZhcG9yYXRpdmUgd2F0ZXIgbG9zcyB7LX0KVGhlIHJlbGF0aXZlIHNraW4gcmVzaXN0YW5jZSwgJHJfaSQsIGlzIGNhbGN1bGF0ZWQgYXM6IAoKXGJlZ2lue2VxdWF0aW9ufQpyX2kgPSByX3QgLSByX2IsCihcI2VxOnJlc3QpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkcl90JCBpcyB0aGUgdG90YWwgcmVzaXN0YW5jZSAocyBjbV4tMV4pIGFuZCAkcl9iJCBpcyB0aGUgYm91bmRhcnkgbGF5ZXIgcmVzaXN0YW5jZSBiYXNlZCBvbiBhbiBlcXVpdmFsZW50IGFnYXIgbW9kZWwgKHMgY21eLTFeKSBvciBoeXBvdGhldGljYWwgYmlvcGh5c2ljYWwgbW9kZWwgXEByZWYoZXE6cmIpLiAkcl90JCBpcyBjYWxjdWxhdGVkIGZvbGxvd2luZyBAU3BvdGlsYTE5NzYgYW5kIEBIaWxsbWFuMjAwOToKClxiZWdpbntlcXVhdGlvbn0Kcl90ID0gXGZyYWN7XHJob317XHRleHRybXtDV0x9fSA9IChccmhvX3t2W3NraW5dfSAtIFxyaG9fdiBcdGltZXMgXHRleHRybXtSSH1fe1tleGN1cnJlbnRdfSkgXHRpbWVzIFx0ZXh0cm17Q1dMfSwKKFwjZXE6dHJlc3QpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkXHJobyQgaXMgdGhlIHZhcG91ciBkZW5zaXR5IGdyYWRpZW50IGF0IHRoZSBzdXJmYWNlIG9mIHRoZSBhbmltYWwgKGcgY21eLTNeKSwgJFx0ZXh0cm17Q1dMfSQgaXMgdGhlIGN1dGFuZW91cyByYXRlcyBvZiBldmFwb3JhdGl2ZSB3YXRlciBsb3NzICgkXHRleHRybXtFV0x9JCkgYnkgc3VyZmFjZSBhcmVhIChnIHNeLTFeIGNtXi0yXiksICRccmhvX3YkIGlzIHRoZSB3YXRlciB2YXBvdXIgZGVuc2l0eSBvZiB3YXRlci1zYXR1cmF0ZWQgYWlyIChnIGNtXi0zXiksICRccmhvX3t2W3NraW5dfSQgaXMgdGhlICRccmhvX3YkIGF0IHRoZSBza2luIHN1cmZhY2UsIGFuZCAkXHRleHRybXtSSH0kIGlzIHRoZSBmcmFjdGlvbmFsIHNhdHVyYXRpb24gKDAtMSkuICRccmhvJCBpcyBjYWxjdWxhdGVkIGFzIHRoZSBkaWZmZXJlbmNlIGluIHRoZSB3YXRlciB2YXBvdXIgZGVuc2l0eSBhdCB0aGUgdGVtcGVyYXR1cmUgb2YgdGhlIGV2YXBvcmF0aW5nIHN1cmZhY2UgYnkgdGhlIHdhdGVyIHZhcG91ciBkZW5zaXR5IGluIHRoZSBhaXIgYXQgJFx0ZXh0cm17Ukh9JCBhcyBmcmFjdGlvbmFsIHNhdHVyYXRpb24gW0BGZWRlcjE5OTJdLgoKJFx0ZXh0cm17RVdMfSQgKGcgc14tMV4pIGNhbiBiZSBtZWFzdXJlZCBncmF2aW1ldHJpY2FsbHkgKGNoYW5nZSBpbiBtYXNzIG92ZXIgdGltZSkgb3IgY2hhbmdlcyBpbiB3YXRlciB2YXBvdXIgcHJlc3N1cmUsICRlJCAoa1BhKSwgb3IgJFx0ZXh0cm17Ukh9JCBiZXR3ZWVuIHRoZSBpbmN1cnJlbnQgYW5kIGV4Y3VycmVudCBhaXIgZm9yIGEgZmxvdy10aHJvdWdoIHN5c3RlbS4gSW4gYSBmbG93LXRocm91Z2ggc3lzdGVtLCAkXHRleHRybXtFV0x9JCBjYW4gYmUgY2FsY3VsYXRlZCBmcm9tIEBIaWxsbWFuMjAwOSBhbmQgQFJpZGRlbGwyMDE3OgoKXGJlZ2lue2VxdWF0aW9ufQpcdGV4dHJte0VXTH0gPSBcZnJhY3tlfXtUIFx0aW1lcyBSX3Z9IFx0aW1lcyBcdGV4dHJte0ZSfSA9IFsoXHJob192IFx0aW1lcyBcdGV4dHJte1JIfV97W2luY3VycmVudF19KSAtIChccmhvX3YgXHRpbWVzIFx0ZXh0cm17Ukh9X3tbZXhjdXJyZW50XX0pXSBcdGltZXMgXHRleHRybXtGUn0sCihcI2VxOmV3bCkKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRUJCBpcyB0ZW1wZXJhdHVyZSBpbiBLZWx2aW4gKEspLCAgJFJfdiQgaXMgdGhlIGdhcyBjb25zdGFudCBmb3Igd2F0ZXIgdmFwb3IgKDQ2MS41IEogS14tMV4ga2deLTFeKSwgYW5kICRcdGV4dHJte0ZSfSQgaXMgdGhlIGZsb3cgcmF0ZSAobWwgc14tMV4pCgojIyMgQm91bmRhcnkgbGF5ZXIgcmVzaXN0YW5jZSB7LX0KVGhlIGJvdW5kYXJ5IGxheWVyIHJlc2lzdGFuY2UgaXMgdGhlIGxheWVyIG9mIGFpciBpbiB3aGljaCBhbiBvYmplY3QgKG9yIG9yZ2FuaXNtKSBleGNoYW5nZXMgaGVhdCBhbmQgbWFzcyB3aXRoIGl0cyBzdXJyb3VuZGluZyBlbnZpcm9ubWVudC4gVGhlIGJvdW5kYXJ5IGxheWVyIGFkZHMgdG8gdGhlIHJlc2lzdGFuY2Ugb2Ygd2F0ZXIgbG9zcyBieSBjaGFuZ2luZyB0aGUgcGh5c2ljYWwgY29uZGl0aW9ucyBvZiB0aGUgbWljcm9jbGltYXRlIGFyb3VuZCB0aGUgb3JnYW5pc20gW0BTZW56YW5vMjAyMl0uIElmICRyX2IkIHdhcyBub3QgcmVwb3J0ZWQgb3Igbm90IGVzdGltYXRlZCBieSBhIHJlcHJlc2VudGF0aXZlIGFnYXIgbW9kZWwsIHdlIHVzZWQgdGhlIHRoZW9yZXRpY2FsICRyX2IkIHdpdGgga25vd24gZm9yY2VkIGNvbnZlY3Rpb24gKCRWJCkgZnJvbSBAUmlkZGVsbDIwMTc6IAoKXGJlZ2lue2VxdWF0aW9ufQpyX2IgPSBcZnJhY3swLjkzIFx0aW1lcyBccmhvIFx0aW1lcyBDX3tccmhvfX17aF9jfSwKKFwjZXE6cmIpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSwgJFxyaG8kICBpcyB0aGUgZGVuc2l0eSBvZiB0aGUgYWlyIChrZyBtXi0zXiksICRDX3tccmhvfSQgaXMgdGhlIHNwZWNpZmljIGhlYXQgb2YgYWlyIChrZ14tMV4gS14tMV4pIGNhbGN1bGF0ZWQgYXM6CgpcYmVnaW57ZXF1YXRpb259CkNfe1xyaG99ID0gXGZyYWN7MTAwNC44NCArICgxODQ2LjQwIFx0aW1lcyByX3cpfXsxICsgcl93fSwKKFwjZXE6Y3ApClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkcl93JCBpcyBtaXhpbmcgcmF0aW8gb2Ygd2F0ZXIgdmFwb3VyIFtAVHJhY3kyMDE5XSBlc3RpbWF0ZWQgdXNpbmc6CgpcYmVnaW57ZXF1YXRpb259CnJfdyA9IFxmcmFjezAuNjIxOTcgXHRpbWVzIDEuMDA1MyBcdGltZXMgZX17cCAtIDEuMDA1MyBcdGltZXMgZX0sCihcI2VxOnJ3KQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJGUkIGlzIHRoZSB2YXBvdXIgcHJlc3N1cmUgKGtQYSkgYW5kICRwJCBpcyB0aGUgYXRtb3NwaGVyaWMgcHJlc3N1cmUgKGtQYSkuICRoX2MkIFxAcmVmKGVxOnJiKSBpcyB0aGUgY29lZmZpY2llbnQgb2YgY29udmVjdGl2ZS1oZWF0IHRyYW5zZmVyIHVuZGVyIGZvcmNlZCBjb252ZWN0aW9uIGFwcHJveGltYXRlZCBieToKClxiZWdpbntlcXVhdGlvbn0KaF9jID0gMC4wOTIzKFZeezAuMDMzM30gXHRpbWVzIEReey0wLjY2Nn0pLAooXCNlcTpoYykKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRWJCBpcyB0aGUgd2luZCBzcGVlZCAobSBzXi0xXikgYW5kICREJCBpcyB0aGUgY2hhcmFjdGVyaXN0aWMgZGltZW5zaW9uIChtKS4gJEQkIGlzIHRoZSBjcm9zcy1zZWN0aW9uYWwgcmFkaXVzLCBhc3N1bWluZyB0aGUgZGltZW5zaW9ucyBvZiBhIHNwaGVyZSBmb3IgYSBmcm9nLCBiYXNlZCBvbiB0aGUgbWFzcyBhbmQgdGhlIHRvdGFsIHN1cmZhY2UgYXJlYS4KCklmIHRoZSBzdHVkeSB3YXMgY29uZHVjdGVkIHVuZGVyIGZyZWUgY29udmVjdGlvbiwgd2UgdXNlZCBhIG1vZGlmaWVkIFxAcmVmKGVxOmhjKSBmcm9tIEBSaWRkZWxsMjAxNzoKClxiZWdpbntlcXVhdGlvbn0KaF9jID0gXGZyYWN7MC40OCBcdGltZXMgXHRleHRybXtHcn1eezAuMjV9IFx0aW1lcyBrfXtEfSwKKFwjZXE6aGNmcmVlKQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJFx0ZXh0cm17R3J9JCBpcyB0aGUgR3Jhc2hvZiBudW1iZXIsICRrJCBpcyB0aGUgdGhlcm1hbCBjb25kdWN0aXZpdHkgb2YgdGhlIGZsdWlkIChXIG1eLTFeIEteLTFeKSAkRCQgaXMgdGhlIGNoYXJhY3RlcmlzdGljIGRpbWVuc2lvbiAobSkuICRcdGV4dHJte0dyfSQgZGVzY3JpYmVzIHRoZSByZWxhdGl2ZSBzdHJlbmd0aCBvZiB0aGUgYnVveWFudCBmb3JjZXMgdG8gdmlzY291cyBmb3JjZSBvZiB0aGUgYWlyIHN1cnJvdW5kaW5nIHRoZSBvYmplY3QgY2FsY3VsYXRlZCBhczoKClxiZWdpbntlcXVhdGlvbn0KXHRleHRybXtHcn0gPSBcZnJhY3tnIFx0aW1lcyBcYmV0YSBcdGltZXMgXERlbHRhe1R9IFx0aW1lcyBEXnszfX17dl57Mn19LAooXCNlcTpncikKXGVuZHtlcXVhdGlvbn0KCndoZXJlICRnJCBpcyB0aGUgYWNjZWxlcmF0aW9uIGJ5IGdyYXZpdHkgKDkuODAgbSBzXi0yXiksICRcYmV0YSQgaXMgdGhlIGNvZWZmaWNpZW50IG9mIHZvbHVtZXRyaWMgZXhwYW5zaW9uICgzLjY3ICRcdGltZXMkIDEwXi0zXiDCsENeLTFeKSwgJEQkIGlzIHRoZSBjaGFyYWN0ZXJpc3RpYyBkaW1lbnNpb24sICR2JCBpcyB0aGUga2luZW1hdGljIHZpc2Nvc2l0eSBmcm9tIEBSaWRkZWxsMjAxNywgYW5kICRcRGVsdGF7VH0kIGlzIGVzdGltYXRlZCBieToKClxiZWdpbntlcXVhdGlvbn0KXERlbHRhe1R9ID0gVF8wKDErMC4zOCBcdGltZXMgZV8wIC8gcCkgLSBUKDErMC4zOCBcdGltZXMgZS9wKSwKKFwjZXE6ZGVsdGEpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkVF8wJCBpcyB0aGUgdGVtcGVyYXR1cmUgKEspIG9mIHRoZSBzdXJmYWNlLCAkZV8wJCBpcyB0aGUgd2F0ZXIgdmFwb3VyIHByZXNzdXJlIGRpcmVjdGx5IGFib3ZlIHRoZSBzdXJmYWNlLCBhbmQgJHAkIGlzIHRoZSBhdG1vc3BoZXJpYyBwcmVzc3VyZSBbQE1vbnRpZXRoMjAxM10uIAoKIyMjIFZhcG91ciBwcmVzc3VyZSBkZWZpY2l0IHstfQpUaGUgdmFwb3VyIHByZXNzdXJlIGRlZmljaXQgKFZQRCkgd2FzIGNhbGN1bGF0ZWQgYXM6CgpcYmVnaW57ZXF1YXRpb259ClZQRCA9IGVfcyAtIGVfYSwKKFwjZXE6dnBkKQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJGVfcyQgaXMgdGhlIHNhdHVyYXRpb24gdmFwb3VyIHByZXNzdXJlIChrUGEpIGF0IGEgZ2l2ZW4gdGVtcGVyYXR1cmUgYW5kICRlX2EkIGlzIHRoZSBhY3R1YWwgdmFwb3VyIHByZXNzdXJlIGluIHRoZSBhaXIgKGtQYSkuICRlX3MkIHdhcyBjYWxjdWxhdGVkIHVzaW5nIHRoZSBDbGF1c2l1cy1DbGFwZXlyb24gZXF1YXRpb24gQFN0dWxsMjAwMDoKClxiZWdpbntlcXVhdGlvbn0KZV9zID0gZV8wIFx0aW1lcyBcZXhwIFxsZWZ0W1xmcmFje0x9e1Jfdn0gXGxlZnQoIFxmcmFjezF9e1RfMH0gLSBcZnJhY3sxfXtUfSBccmlnaHQpIFxyaWdodF0sCihcI2VxOmVzKQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJGVfMCQgPSAwLjYxMSBrUGEgYW5kICRUXzAkIOKAkyAyNzMgSyBhcmUgY29uc3RhbnQgcGFyYW1ldGVycywgYW5kICRSX3YkIOKAkyA0NjEuNSBKIEteLTFeIEtnXi0xXiBhbmQgJEwkID0gMi41IHggMTA2IEoga2deLTFeIGFyZSBnYXMgY29uc3RhbnQgZm9yIHdhdGVyIHZhcG91ciBhbmQgdGhlIGxhdGVudCBoZWF0IG9mIHZhcG91cml6YXRpb24sIHJlc3BlY3RpdmVseS4gICRUJCAoYXMgSykgaXMgdGhlIGFjdHVhbCB0ZW1wZXJhdHVyZSBtZWFzdXJlZC4gJGVfYSQgd2FzIGFwcHJveGltYXRlZCBhczoKClxiZWdpbntlcXVhdGlvbn0KZV9hID0gXGZyYWN7XHRleHRybXtSSH0gXHRpbWVzIGVfc317MTAwfSwKKFwjZXE6ZWEpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkXHRleHRybXtSSH0kIGlzIHRoZSBtZWFzdXJlZCByZWxhdGl2ZSBodW1pZGl0eSAoJSkuCgojIyMgU3VyZmFjZSBhcmVhIHstfQpGb3Igc3R1ZGllcyB0aGF0IHByZXNlbnRlZCBFV0wgYW5kIFdVIHdpdGhvdXQgY29ycmVjdGluZyBmb3Igc3VyZmFjZSBhcmVhLCB3ZSBjb3JyZWN0ZWQgdG8gc3VyZmFjZSBhcmVhIGJ5IGRpdmlkaW5nIHRoZSBhYnNvbHV0ZSByYXRlcyBieSAyLzMgb2YgdGhlIHRvdGFsIHN1cmZhY2UgYXJlYSBmb3IgRVdMLCB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgYXJlYSBleHBvc2VkIHRvIGFpciB3aGVuIGFudXJhbnMga2VlcCB0aGUgd2F0ZXIgY29uc2VydmF0aW9uIHBvc3R1cmUgW0BXaXRoZXJzMTk4MjsgQFdpdGhlcnMxOTg0XS4gRm9yIFdVLCB3ZSBjb3JyZWN0ZWQgdG8gc3VyZmFjZSBhcmVhIGJ5IGRpdmlkaW5nIHRoZSBhYnNvbHV0ZSByYXRlcyBieSAxLzMgb2YgdGhlIHRvdGFsIHN1cmZhY2UgYXJlYSBiZWNhdXNlIFdVIHByaW1hcmlseSBvY2N1cnMgaW4gdGhlIHBlbHZpYyAnc2VhdCBwYXRjaCcgcmVnaW9uIG9mIHRoZSB2ZW50cmFsIHNraW4gW0BCYWxkd2luMTk3NDsgQE1jQ2xhbmFoYW4xOTY5OyBAV2lsbHVtc2VuMjAwN10uIFRvdGFsIHN1cmZhY2UgYXJlYSAoY21eMl4pIHdhcyBlc3RpbWF0ZWQgdmlhIGZhbWlseS1zcGVjaWZpYyBtYXNzLXN1cmZhY2UgYXJlYSBzY2FsaW5nIHJlbGF0aW9uc2hpcCBmcm9tIEBLbGVpbjIwMTY6CgpcYmVnaW57ZXF1YXRpb259ClNBID0gXGJldGFfMCBNXntcYmV0YV8xfSwKKFwjZXE6c2EpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkXGJldGFfMCQgaXMgdGhlIGludGVyY2VwdCwgJE0kIGlzIHRoZSBhbmltYWwgYm9keSBtYXNzIChnKSwgYW5kICRcYmV0YV8xJCBpcyB0aGUgc2xvcGUuIElmIHRoZSBmYW1pbHktc3BlY2lmaWMgbWFzcy1zdXJmYWNlIGFyZWEgc2NhbGluZyByZWxhdGlvbnNoaXAgd2FzIG5vdCBwcmVzZW50ZWQsIHdlIHVzZWQgdGhlIHBvd2VyIGVxdWF0aW9uIGZvciBhbGwgQW51cmEgKDkuODUzNyRNJF4wLjY3NDVeKSBhcyBhIGNvbnNlcnZhdGl2ZSBlc3RpbWF0ZS4KCiMjIyBQZXJjZW50YWdlIG1hc3MgY2hhbmdlIHRvIGFjdHVhbCBtYXNzIGNoYW5nZSB7LX0KCkZvciBzdHVkaWVzIHRoYXQgcHJlc2VudGVkICUgY2hhbmdlIGluIG1hc3MgKCRcRGVsdGEgTSQpIHdpdGggcmF3IGRhdGEgYXZhaWxhYmxlIG9uIGluaXRpYWwgbWFzcywgd2UgY29udmVydGVkIHBlcmNlbnRhZ2UgY2hhbmdlIGluIG1hc3MgKCUgaF4tMV4pIGJhY2sgdG8gYWJzb2x1dGUgbWFzcyBjaGFuZ2UgKGcgaF4tMV4pIGZvbGxvd2luZzogCgpcYmVnaW57ZXF1YXRpb259Clx0ZXh0cm17RVdMfSA9IE0gXHRpbWVzIFxsZWZ0KFxmcmFje1xEZWx0YSBNfXsxMDB9XHJpZ2h0KSwKKFwjZXE6ZXdscGVyKQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJE0kIGlzIHRoZSBpbml0aWFsIGJvZHkgbWFzcyAoZyksIGFuZCAkXERlbHRhIE0kIGlzIHRoZSBwZXJjZW50YWdlIGNoYW5nZSBpbiBtYXNzICglIGheLTFeKS4gTm90ZSwgc3R1ZGllcyB3aXRoICUgY2hhbmdlIGluIGJvZHkgbWFzcyB3aXRob3V0IHRoZSBpbml0aWFsIGJvZHkgbWFzcyBwcmVzZW50ZWQgd2VyZSBub3QgaW5jbHVkZWQgaW4gdGhlIGRhdGEgZXh0cmFjdGlvbi4KCioqKgoKIyBEYXRhc2V0IHstfQoKTG9hZCBhbmQgY2xlYW4gdGhlIHJhdyBkYXRhc2V0IGByYXdfZGF0YS5jc3ZgLgoKYGBge3IgY2xlYW4sIG1lc3NhZ2U9RkFMU0V9CiMgTG9hZCBhbmQgY2xlYW4gcmF3IGRhdGEKcmF3X2RhdCA8LSByZWFkLmNzdihmaWxlLnBhdGgoZGF0YV9wYXRoLCAicmF3X2RhdGEuY3N2IikpICU+JQogIGRwbHlyOjpzZWxlY3Qoc3R1ZHlfSUQ6dW5pdCwgcl9zX2VzdCwgY2FsY3VsYXRlZCkgJT4lCiAgZHBseXI6Om11dGF0ZShlY290eXBlICA9IGZhY3RvcihlY290eXBlKSwKICAgICAgICAgZmFtaWx5ICAgPSBmYWN0b3IoZmFtaWx5KSwKICAgICAgICAgb3JpZ2luICAgPSBmYWN0b3Iob3JpZ2luKSwKICAgICAgICAgc3RyYXRlZ3kgPSBmYWN0b3IoY2FzZV93aGVuKHN0cmF0ZWd5ID09ICIiIH4gIm5vbmUiLCBUUlVFIH4gYXMuY2hhcmFjdGVyKHN0cmF0ZWd5KSkpLAogICAgICAgICBzdHJhdGVneSA9IGZjdF9yZWxldmVsKHN0cmF0ZWd5LCAibm9uZSIsICJ3YXRlci1wcm9vZiIsICJjb2Nvb24iLCAiaG9sbG93IiksCiAgICAgICAgIHRyYWl0ICAgID0gZmFjdG9yKHRyYWl0KSwKICAgICAgICAgcmVzcG9uc2UgPSBmYWN0b3IocmVzcG9uc2UpLAogICAgICAgICBsbk1hc3MgICA9IGxvZyhtZWFuX21hc3NfZyksCiAgICAgICAgIGxuRmxvdyAgID0gbG9nKGFpcmZsb3dfY21fcyArIDEpLAogICAgICAgICBlc19rUGEgICA9IGlmZWxzZSh0cmFpdCA9PSAid2F0ZXIgbG9zcyIsIDAuNjExICogZXhwKDI1MDAwMDAgLyA0NjEuNSAqICgxIC8gMjczIC0gMSAvICh0cnRfdGVtcCArIDI3My4xNSkpKSwgTkEpLCAjIHNhdHVyYXRpb24gdmFwb3IgcHJlc3N1cmUgKGtQYSkgYXQgYSBnaXZlbiB0ZW1wZXJhdHVyZQogICAgICAgICBlYV9rUGEgICA9IGlmZWxzZSh0cmFpdCA9PSAid2F0ZXIgbG9zcyIsIFJIX3BlcmMgKiBlc19rUGEgLyAxMDAsIE5BKSwgIyBhY3R1YWwgdmFwb3IgcHJlc3N1cmUgKGtQYSkKICAgICAgICAgVlBEX2tQYSAgPSBlc19rUGEgLSBlYV9rUGEsCiAgICAgICAgIGxuVlBEICAgID0gbG9nKFZQRF9rUGEpKSAlPiUKICBkcGx5cjo6ZmlsdGVyKHNwZWNpZXNfcGh5bG8gIT0gIiIpICMgcmVtb3ZlIHJvd3Mgd2l0aCBubyBzcGVjaWVzCgpld2xfZGF0IDwtIHJhd19kYXQgJT4lCiAgZHBseXI6OmZpbHRlcihyZXNwb25zZSA9PSAiZXZhcG9yYXRpdmUgd2F0ZXIgbG9zcyIgJiAhaXMubmEodW5pdF9jb3JyZWN0ZWRfbWVhbikpICU+JQogIGRwbHlyOjptdXRhdGUobWdfaF9tZWFuID0gdW5pdF9jb3JyZWN0ZWRfbWVhbiAqIGRvcnNfU0FfY20yLAogICAgICAgICAgICAgICAgbWdfaF9zZCAgID0gdW5pdF9jb3JyZWN0ZWRfc2QgKiBkb3JzX1NBX2NtMiwgICAgCiAgICAgICAgICAgICAgICBsbk1lYW4gICAgPSBsb2cobWdfaF9tZWFuKSwKICAgICAgICAgICAgICAgIHYgICAgICAgICA9IG1nX2hfc2ReMiAvIHNhbXBsZV9zaXplLCAjIHNhbXBsaW5nIHZhcmlhbmNlICh2KQogICAgICAgICAgICAgICAgc2VpICAgICAgID0gc3FydCh2KSwgIyBzdGFuZGFyZCBlcnJvciAoU0UpCiAgICAgICAgICAgICAgICBpbnYgICAgICAgPSAxIC8gc2VpLCAjIHByZWNpc2lvbiAoaW52ZXJzZSBvZiBTRSkgKQogICAgICAgICAgICAgICAgdyAgICAgICAgID0gMSAvIHYsICMgd2VpZ2h0IChpbnZlcnNlIG9mIHZhcmlhbmNlKSAKICAgICAgICAgICAgICAgIGhfNzAgICAgICA9IChtZWFuX21hc3NfZyAtIChtZWFuX21hc3NfZyAqIDAuNykpIC8gKG1nX2hfbWVhbiAqIDAuMDAxKSkgCgpyZXNpc3RfZGF0IDwtIHJhd19kYXQgJT4lCiAgZHBseXI6OmZpbHRlcighaXMubmEocl9zX2VzdCkpICU+JQogIGRwbHlyOjptdXRhdGUobG5NZWFuID0gbG9nKHJfc19lc3QgKyAxKSkKCnd1X2RhdCA8LSByYXdfZGF0ICU+JQogIGRwbHlyOjpmaWx0ZXIodHJhaXQgPT0gIndhdGVyIGdhaW4iICYgIWlzLm5hKHVuaXRfY29ycmVjdGVkX21lYW4pKSAlPiUKICBkcGx5cjo6bXV0YXRlKG1nX2hfbWVhbiA9IHVuaXRfY29ycmVjdGVkX21lYW4gKiB2ZW50X1NBX2NtMiwKICAgICAgICAgICAgICAgIG1nX2hfc2QgICA9IHVuaXRfY29ycmVjdGVkX3NkICogdmVudF9TQV9jbTIsCiAgICAgICAgICAgICAgICBsbk1lYW4gICAgPSBsb2cobWdfaF9tZWFuKSwKICAgICAgICAgICAgICAgIHYgICAgICAgICA9IG1nX2hfc2ReMiAvIHNhbXBsZV9zaXplLCAjIHNhbXBsaW5nIHZhcmlhbmNlICh2KQogICAgICAgICAgICAgICAgc2VpICAgICAgID0gc3FydCh2KSwgIyBzdGFuZGFyZCBlcnJvciAoU0UpCiAgICAgICAgICAgICAgICBpbnYgICAgICAgPSAxIC8gc2VpKSAjIHByZWNpc2lvbiAoaW52ZXJzZSBvZiBTRSkKCiNld2xfZGF0ICU+JQogICNncm91cF9ieShzdHJhdGVneSkgJT4lCiAgI3N1bW1hcmlzZShtZWFuID0gbWVhbihoXzcwLCBuYS5ybSA9IFRSVUUpKQpgYGAKClRoZXJlIGFyZSBgciBsZW5ndGgodW5pcXVlKGV3bF9kYXQkc3BlY2llc19waHlsbykpYCBzcGVjaWVzIHdpdGggZGF0YSBvbiBldmFwb3JhdGl2ZSB3YXRlciBsb3NzIChgciBsZW5ndGgodW5pcXVlKGV3bF9kYXQkc3R1ZHlfSUQpKWAgc3R1ZGllcyksIGByIGxlbmd0aCh1bmlxdWUocmVzaXN0X2RhdCRzcGVjaWVzX3BoeWxvKSlgIHNwZWNpZXMgd2l0aCBza2luIHJlc2lzdGFuY2UgZGF0YSAoYHIgbGVuZ3RoKHVuaXF1ZShyZXNpc3RfZGF0JHN0dWR5X0lEKSlgIHN0dWRpZXMpLCBhbmQgYHIgbGVuZ3RoKHVuaXF1ZSh3dV9kYXQkc3BlY2llc19waHlsbykpYCBzcGVjaWVzIHdpdGggd2F0ZXIgdXB0YWtlIGRhdGEgKGByIGxlbmd0aCh1bmlxdWUod3VfZGF0JHN0dWR5X0lEKSlgIHN0dWRpZXMpLiBXZSB1c2VkIHRoZSBldmFwb3JhdGl2ZSB3YXRlciBsb3NzIHRvIGFuYWx5c2UgZGlmZmVyZW5jZXMgYmV0d2VlbiBlY290eXBlIGFzIHRoZXJlIGFyZSBtb3JlIHNwZWNpZXMgcmVwcmVzZW50ZWQgY29tcGFyZWQgdG8gdGhlIHNraW4gcmVzaXN0YW5jZSBkYXRhLiBUaGVyZSB3ZXJlIHRocmVlIHNwZWNpZXMgdGhhdCB3ZXJlIGV4Y2x1ZGVkIGZyb20gdGhlIGFuYWx5c2lzIGJlY2F1c2UgdGhleSB3ZXJlIG5vdCBsaXN0ZWQgaW4gdGhlIElVQ04gUmVkIExpc3QgYW5kIHdlcmUgbm90IHByZXNlbnQgaW4gdGhlIHBoeWxvZ2VuZXRpYyB0cmVlIGZyb20gQEpldHoyMDE4OiAqQnJhY2h5Y2VwaGFsdXMgcGl0YW5nYSosICpFbGFjaGlzdG9jbGVpcyBjZXNhcmlpKiwgYW5kICpMZXB0b2RhY3R5bHVzIGx1Y3RhdG9yKi4KCiMjIEdlb2dyYXBoaWNhbCBiaWFzIGluIGh5ZHJvcmVndWxhdGlvbiBzdHVkaWVzIHstfQoKYGBge3IgRmlnIFM0LCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9My41LCBmaWcud2lkdGg9NywgZWNobyA9IEZBTFNFfQp3aWxkX2RhdCA8LSByYXdfZGF0ICU+JSBkcGx5cjo6ZmlsdGVyKG9yaWdpbiA9PSAid2lsZCIpCmxhYl9kYXQgIDwtIHJhd19kYXQgJT4lIGRwbHlyOjpmaWx0ZXIob3JpZ2luID09ICJsYWIiKQoKd29ybGRfbWFwIDwtIG1hcF9kYXRhKCJ3b3JsZCIpCnJhd19kYXQgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fbWFwKGRhdGEgPSB3b3JsZF9tYXAgJT4lIGRwbHlyOjpmaWx0ZXIocmVnaW9uICE9ICJBbnRhcmN0aWNhIiksIG1hcCA9IHdvcmxkX21hcCwgYWVzKGxvbmcsIGxhdCwgbWFwX2lkID0gcmVnaW9uKSwgZmlsbCA9ICIjZGVkZWRlIiwgY29sb3VyID0gTkEpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gbG9uLCB5ID0gbGF0KSwgc2hhcGUgPSAyMSwgZmlsbCA9ICJ3aGl0ZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWVfdm9pZCgpICsgCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZCgpCmBgYAoKKipGaWcuIFM0LioqIFNwYXRpYWwgZGlzdHJpYnV0aW9uIG9mIGh5ZHJvcmVndWxhdGlvbiBzdHVkaWVzIHVzaW5nIHdpbGQgY2F1Z2h0IGFudXJhbnMgKHN0dWR5ICpuKiA9IGByIGxlbmd0aCh1bmlxdWUod2lsZF9kYXQkc3R1ZHlfSUQpKWApLiBgciBsZW5ndGgodW5pcXVlKGxhYl9kYXQkc3R1ZHlfSUQpKWAgc3R1ZGllcyB1c2VkIGNhcHRpdmUgcmFpc2VkIGFudXJhbnMuIFRoZXJlIGFyZSBsYXJnZSByZWdpb25zIGFyb3VuZCBjZW50cmFsIEFmcmljYSBhbmQgRXVyYXNpYSB3aXRoIGhpZ2ggYW1waGliaWFuIGRpdmVyc2l0eSwgYnV0IG5vIGh5ZHJvbG9naWNhbCBzdHVkaWVzIGNvbmR1Y3RlZCAoKipGaWcuIDFiKiopLiAKCioqKgoKIyMgUHJlcGFyZSBwaHlsb2dlbnkgZm9yIGFuYWx5c2lzIHstfQoKVGhlIHBoeWxvZ2VueSB3YXMgb2J0YWluZWQgZnJvbSBASmV0ejIwMTggY29tcHJpc2luZyBvZiA3LDIzOCBzcGVjaWVzLiBUaGUgdHJlZSB3YXMgcHJ1bmVkIHRvIG1hdGNoIHRoZSBgciBsZW5ndGgodW5pcXVlKHJhd19kYXQkc3BlY2llc19waHlsbykpYCBzcGVjaWVzIGV4dHJhY3RlZCBmb3IgdGhlIHN1YnNlcXVlbnQgYW5hbHlzaXMuCgpgYGB7ciBwaHlsbywgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0iaGlkZSJ9CiMgTG9hZCB0cmVlCnBoeWxvX3RyZWUgPC0gYXBlOjpyZWFkLnRyZWUoZmlsZS5wYXRoKGRhdGFfcGF0aCwgImFtcGhfc2hsX25ld19Db25zZW5zdXNfNzIzOC50cmUiKSkKCiMgUHJ1bmluZyBkYXRhIGFuZCBwaHlsb2dlbnkKdHJlZV90aXBfbGFiZWwgPC0gcGh5bG9fdHJlZSR0aXAubGFiZWwgIyBleHRyYWN0IHRyZWUgdGlwIG5hbWVzCnNwX2xpc3QgICAgICAgIDwtIHJhd19kYXQkc3BlY2llc19waHlsbyAjIGV4dHJhY3Qgc3BlY2llcyBuYW1lIGZyb20gbWVhbiBkYXRhCnBydW5lZF90cmVlICAgIDwtIGFwZTo6ZHJvcC50aXAocGh5bG9fdHJlZSwgc2V0ZGlmZihwaHlsb190cmVlJHRpcC5sYWJlbCwgc3BfbGlzdCkpICMgcHJ1bmUgcGh5bG9fdHJlZSB0byBrZWVwIHNwZWNpZXMgZnJvbSB0aGUgcmF3IGRhdGEKcHJ1bmVkX3RyZWUgICAgPC0gcGh5dG9vbHM6OmZvcmNlLnVsdHJhbWV0cmljKHBydW5lZF90cmVlLCBtZXRob2QgPSAiZXh0ZW5kIikgIyB1bHRyYW1ldHJpY2l6ZSB0aGUgdHJlZQpwaHlsb19jb3IgICAgICA8LSB2Y3YocHJ1bmVkX3RyZWUsIGNvciA9IFQpCgpzZXRkaWZmKHJhd19kYXQkc3BlY2llc19waHlsbywgcm93bmFtZXMocGh5bG9fY29yKSkKc2V0ZGlmZihyb3duYW1lcyhwaHlsb19jb3IpLCByYXdfZGF0JHNwZWNpZXNfcGh5bG8pCgojYXBlOjppcy51bHRyYW1ldHJpYyhwcnVuZWRfdHJlZSkKYGBgCgojIEFuYWx5c2lzIHstfQoKVGhlIG9yaWdpbmFsIG1vZGVsIGluY29ycG9yYXRlZCBvcmlnaW4gKGxhYi1yYWlzZWQgb3Igd2lsZC1jYXVnaHQpIGFuZCB3aGV0aGVyIHRoZSBibGFkZGVyIHdhcyB2b2lkIG9mIHVyaW5lIHByaW9yIHRvIHRoZSBleHBlcmltZW50LiBIb3dldmVyLCB0aGUgbW9kZWwncyBidWxrIGVmZmVjdGl2ZSBzYW1wbGVzIHNpemUgKEVTUykgd2FzIHRvbyBsb3csIGluZGljYXRpbmcgcG9zdGVyaW9yIG1lYW5zIGFuZCBtZWRpYW5zIG1heSBiZSB1bnJlbGlhYmxlLiBTaW5jZSBvcmlnaW4gYW5kIHdoZXRoZXIgdGhlIGJsYWRkZXIgd2FzIGVtcHRpZWQgZGlkIG5vdCBpbmZsdWVuY2UgJHJfaSQsIHRoZXkgd2VyZSBleGNsdWRlZCBpbiB0aGUgZmluYWwgbW9kZWwuIEZvciB0cmFuc3BhcmVuY3ksIG9uIGF2ZXJhZ2UsIHdpbGQtY2F1Z2h0IGFudXJhbnMgaGFkLCBvbiBhdmVyYWdlLCBoaWdoZXIgJHJfaSQgcmVsYXRpdmUgdG8gbGFiLXJhaXNlZCBhbnVyYW5zICgwLjA4IFstMC40NzowLjMxXSksIGFuZCBhbnVyYW5zIHdpdGggdGhlaXIgYmxhZGRlciB2b2lkZWQgb2YgdXJpbmUgaGFkIGhpZ2hlciAkcl9pJCAoMC4xNyBbLTAuNTk6IDAuMjVdKS4gSG93ZXZlciB0aGVyZSBpcyBzdWJzdGFudGlhbCB2YXJpYWJpbGl0eSBiZXR3ZWVuIHRoZSB3aWxkLWNhdWdodCBhbmQgbGFiLXJhaXNlZCBncm91cHMsIGFuZCB3aGV0aGVyIGFudXJhbnMgd2l0aCB0aGVpciBibGFkZGVyIHZvaWRlZCBvciBub3QuCgpgYGB7ciBhbmFseXNpcywgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9CiNvcHRpb25zKGJybXMuYmFja2VuZCA9ICJjbWRzdGFuciIpICMgRXJyb3IgZnJvbSB1c2luZyBSc3RhbnMgImVycm9yIGluIHVuc2VyaWFsaXplKHNvY2tsaXN0W1tuXV0pIDogZXJyb3IgcmVhZGluZyBmcm9tIGNvbm5lY3Rpb24iLiBVc2VkIGNtZHN0YW5yIGFyb3VuZCBpdC4KCnByaW9ycyA8LSBjKHByaW9yKG5vcm1hbCgwLCAzKSwgJ2InKSwgCiAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAzKSwgJ0ludGVyY2VwdCcpLAogICAgICAgICAgICBwcmlvcihzdHVkZW50X3QoMywgMCwgMTApLCAnc2QnKSwgCiAgICAgICAgICAgIHByaW9yKHN0dWRlbnRfdCgzLCAwLCAxMCksICdzaWdtYScpKQoKcmlfbW9kZWwgPC0gYnJtczo6YnJtKGxuTWVhbiB+IGVjb3R5cGUgKyBzdHJhdGVneSArIGxuTWFzcyArIGxuVlBEICsgbG5GbG93ICsgKDEgfCBzdHVkeV9JRCkgKyAoMSArIGxuTWFzcyB8IHNwZWNpZXNfaXVjbikgKyAoMSB8IGdyKHNwZWNpZXNfcGh5bG8sIGNvdiA9IHBoeWxvKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSAgICA9IHJlc2lzdF9kYXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ICA9IGdhdXNzaWFuKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTIgICA9IGxpc3QocGh5bG8gPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IgICA9IHByaW9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucyAgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzICAgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgICAgPSA1ZTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FybXVwICA9IDIuNWUzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45OSwgbWF4X3RyZWVkZXB0aCA9IDE1KSkKCnd1X21vZGVsIDwtIGJybXM6OmJybShsbk1lYW4gfiBlY290eXBlICsgbG5NYXNzICsgdHJ0X3RlbXAgKyBoeWRyYXRpb24gKyBvcmlnaW4gKyAoMSB8IHN0dWR5X0lEKSArICgxICsgbG5NYXNzIHwgc3BlY2llc19pdWNuKSArICgxIHwgZ3Ioc3BlY2llc19waHlsbywgY292ID0gcGh5bG8pKSwgCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YSAgICA9IHd1X2RhdCAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShlY290eXBlKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIobigpID49IDUpLCAKICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgID0gZ2F1c3NpYW4oKSwgCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YTIgICA9IGxpc3QocGh5bG8gPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgIHByaW9yICAgPSBwcmlvcnMsCiAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zICA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgIGNvcmVzICAgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICBpdGVyICAgID0gNWUzLCAKICAgICAgICAgICAgICAgICAgICAgICB3YXJtdXAgID0gMi41ZTMsIAogICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45OSwgbWF4X3RyZWVkZXB0aCA9IDE1KSkKYGBgCgpgYGB7ciBGaWcgUzUsIGVjaG8gPSBGQUxTRSwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDMsIGZpZy5hbGlnbiA9JyBjZW50ZXInfQpyaV9tb2RlbF9wcCA8LSBicm1zOjpwcF9jaGVjayhyaV9tb2RlbCwgdHlwZSA9ICJzY2F0dGVyX2F2ZyIpICsgbXl0aGVtZSgpCnd1X21vZGVsX3BwICA8LSBicm1zOjpwcF9jaGVjayh3dV9tb2RlbCwgdHlwZSA9ICJzY2F0dGVyX2F2ZyIpICsgbXl0aGVtZSgpCgpjb3dwbG90OjpwbG90X2dyaWQocmlfbW9kZWxfcHAsIHd1X21vZGVsX3BwLCBuY29sID0gMiwgbGFiZWxzID0gYygnYScsICdiJykpCmBgYAoKKipGaWcuIFM1LioqIFNjYXR0ZXJwbG90cyBvZiB0aGUgb2JzZXJ2ZWQgZGF0YSAoeSkgdnMgdGhlIGF2ZXJhZ2Ugc2ltdWxhdGVkIGRhdGEgKHl+cmVwfikgZnJvbSB0aGUgcG9zdGVyaW9yIHByZWRpY3RpdmUgZGlzdHJpYnV0aW9uIGZvciB0aGUgKCoqYSoqKSByZXNpc3RhbmNlIHRvIHdhdGVyIGxvc3MgbW9kZWwsIGFuZCAoKipiKiopIHRoZSB3YXRlciB1cHRha2UgbW9kZWwuIERhc2hlZCBsaW5lIHJlcHJlc2VudHMgYSBzbG9wZSBvZiAxLiAKCiMjIE1vZGVsIG91dHB1dCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfQoKIyMjIFRhYmxlIFMzIC0gJHJfaSQgbW9kZWwgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgoqKlRhYmxlIFMzLioqIE1lYW4gcGFyYW1ldGVyIGVzdGltYXRlcywgZXN0aW1hdGUgZXJyb3IsIGFuZCA5NSUgQmF5ZXNpYW4gY3JlZGlibGUgaW50ZXJ2YWxzIGZvciB0aGUgJHJfaSQgbW9kZWwsIHdoaWNoIGluY2x1ZGVzIHRoZSBpbnRlcmNlcHQgKCRcYmV0YV8wJCksIGVjb3R5cGUsIHN0cmF0ZWd5LCB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgYm9keSBtYXNzIChsbk1hc3MpLCB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgdmFwb3VyIHByZXNzdXJlIGRlZmljaXQgKGxuVlBEKSwgYW5kIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiB0aGUgZXhwZXJpbWVudGFsIGZsb3cgcmF0ZSAobG5GbG93KS4gR3JvdXAtbGV2ZWwgZWZmZWN0cyBpbmNsdWRlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb25zICgkXHNpZ21hJCkgZm9yIHN0dWR5LWxldmVsIG9ic2VydmF0aW9ucyAoJFxzaWdtYV97c3R1ZHl9XjIkKSwgcGh5bG9nZW5ldGljIHJlbGF0ZWRuZXNzICgkXHNpZ21hX3twaHlsb2dlbnl9XjIkKSwgYW5kIHRoZSBjb3JyZWxhdGlvbiBhbW9uZyBzcGVjaWVzICgkXHNpZ21hX3tzcGVjaWVzfV4yJCkgYW5kIGJvZHkgbWFzcyAoJFxzaWdtYV97bG5NYXNzfV4yJCkuICRSX3ttYXJnaW5hbH1eMiQgcmVwcmVzZW50cyB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGZpeGVkIGVmZmVjdHMsIHdoaWxlICRSX3tjb25kaXRpb25hbH1eMiQgcmVwcmVzZW50cyB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGJvdGggZml4ZWQgZWZmZWN0cyBhbmQgZ3JvdXAtbGV2ZWwgZWZmZWN0cy4KCmBgYHtyIHRhYmxlUzMsIGVjaG8gPSBGQUxTRX0KIyBGaXhlZCBlZmZlY3QKZmVmIDwtIGJybXM6OmZpeGVmKHJpX21vZGVsKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSguKSAlPiUKICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiUGFyYW1ldGVyIikgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gc3RyX3JlcGxhY2UoUGFyYW1ldGVyLCAiTSIsICItIikpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9IGNhc2Vfd2hlbigKICAgIFBhcmFtZXRlciA9PSAiSW50ZXJjZXB0IiB+ICJsbiRcXGJldGFfMCQiLAogICAgUGFyYW1ldGVyID09ICJlY290eXBlQXJib3JlYWwiICB+ICJBcmJvcmVhbCIsCiAgICBQYXJhbWV0ZXIgPT0gImVjb3R5cGVGb3Nzb3JpYWwiICB+ICJGb3Nzb3JpYWwiLAogICAgUGFyYW1ldGVyID09ICJlY290eXBlR3JvdW5kLWR3ZWxsaW5nIiAgfiAiR3JvdW5kLWR3ZWxsaW5nIiwKICAgIFBhcmFtZXRlciA9PSAiZWNvdHlwZVNlbWktYXF1YXRpYyIgIH4gIlNlbWktYXF1YXRpYyIsCiAgICBQYXJhbWV0ZXIgPT0gImVjb3R5cGVTdHJlYW0tZHdlbGxpbmciICB+ICJTdHJlYW0tZHdlbGxpbmciLAogICAgUGFyYW1ldGVyID09ICJzdHJhdGVneXdhdGVyLXByb29mIiAgfiAiV2F0ZXItcHJvb2YiLAogICAgUGFyYW1ldGVyID09ICJzdHJhdGVneWNvY29vbiIgIH4gIkNvY29vbiIsCiAgICBQYXJhbWV0ZXIgPT0gInN0cmF0ZWd5aG9sbG93IiAgfiAiSG9sbG93IiwKICAgIFBhcmFtZXRlciA9PSAibG4tYXNzIiAgfiAibG5NYXNzIiwKICAgIFBhcmFtZXRlciA9PSAibG5WUEQiICB+ICJsblZQRCIsCiAgICBQYXJhbWV0ZXIgPT0gImxuRmxvdyIgIH4gImxuRmxvdyIpLAogICAgKSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkZpeGVkIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSYW5kb20gZWZmZWN0CnJlZiA8LSBzdW1tYXJ5KHJpX21vZGVsKSRyYW5kb20gJT4lIAogIGJpbmRfcm93cygpICU+JSAjIHVubGlzdAogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJQYXJhbWV0ZXIiKSAlPiUgCiAgZHBseXI6OnNlbGVjdCgxOjUpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9IGMoIiRcXHNpZ21hX3tzcGVjaWVzfV4yJCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe2xuTWFzc31eMiQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvcigkXFxzaWdtYV97c3BlY2llc31eMiQsICRcXHNpZ21hX3tsbk1hc3N9XjIkKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3BoeWxvZ2VueX1eMiQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiRcXHNpZ21hX3tzdHVkeX1eMiQiKSkgJT4lICAgCiAgZHBseXI6OnJlbmFtZShRMi41ICA9IDQsIAogICAgICAgICAgICAgICAgUTk3LjUgPSA1KSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkdyb3VwLWxldmVsIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKcmlfbGFtYmRhIDwtIGh5cG90aGVzaXMocmlfbW9kZWwsICJzZF9zcGVjaWVzX3BoeWxvX19JbnRlcmNlcHReMiAvIChzZF9zcGVjaWVzX3BoeWxvX19JbnRlcmNlcHReMiArIHNpZ21hXjIpID0gMCIsIGNsYXNzID0gTlVMTCkkaHlwb3RoZXNpcyAlPiUgCiAgZHBseXI6OnNlbGVjdCgtYygxLDY6OCkpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9ICIkXFxsYW1iZGEkIikgJT4lIAogIGRwbHlyOjpyZW5hbWUoUTIuNSAgPSBDSS5Mb3dlciwgCiAgICAgICAgICAgICAgICBROTcuNSA9IENJLlVwcGVyKSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKlBoeWxvZ2VuZXRpYyBzaWduYWwqKiIsIC5iZWZvcmUgPSAxKQoKcmlfcjIgPC0gZGF0YS5mcmFtZShQYXJhbWV0ZXIgPSAiJFJfe21hcmdpbmFsfV4yJCIsCiAgICAgICAgICAgICAgICAgICAgIEVzdGltYXRlID0gcm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMocmlfbW9kZWwpKVsyLDFdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgUTIuNSAgICAgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhyaV9tb2RlbCkpWzIsNF0sIDQpICogMTAwLAogICAgICAgICAgICAgICAgICAgICBROTcuNSAgICA9IHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKHJpX21vZGVsKSlbMiw1XSwgNCkgKiAxMDApICU+JQogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiJFJfe2NvbmRpdGlvbmFsfV4yJCIsCiAgICAgICAgICAgICAgICAgICAgIEVzdGltYXRlID0gcm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMocmlfbW9kZWwpKVsxLDFdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgUTIuNSAgICAgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhyaV9tb2RlbCkpWzEsNF0sIDQpICogMTAwLAogICAgICAgICAgICAgICAgICAgICBROTcuNSAgICA9IHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKHJpX21vZGVsKSlbMSw1XSwgNCkgKiAxMDApICU+JSAKICB0aWJibGU6OmFkZF9yb3coUGFyYW1ldGVyID0gIioqVmFyaWFuY2UqKiIsIC5iZWZvcmUgPSAxKQoKIyBSZW5kZXIgdGFibGUKYmluZF9yb3dzKGZlZiwgcmVmLCByaV9sYW1iZGEsIHJpX3IyKSAlPiUgCiAgcmVtb3ZlX3Jvd25hbWVzKCkgJT4lIAogIGtuaXRyOjprYWJsZShkaWdpdHMgPSAyKQpgYGAKCioqKgoKIyMjIFRhYmxlIFM0IC0gV1UgbW9kZWwgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgoqKlRhYmxlIFM0LioqIE1lYW4gcGFyYW1ldGVyIGVzdGltYXRlcywgZXN0aW1hdGUgZXJyb3IsIGFuZCA5NSUgQmF5ZXNpYW4gY3JlZGlibGUgaW50ZXJ2YWxzIGZvciB0aGUgd2F0ZXIgdXB0YWtlIG1vZGVsLCB3aGljaCBpbmNsdWRlcyB0aGUgaW50ZXJjZXB0ICgkXGJldGFfMCQpLCBlY290eXBlLCB0aGUgbmF0dXJhbCBsb2dhcml0aG0gb2YgYm9keSBtYXNzIChsbk1hc3MpLCB0cmVhdG1lbnQgdGVtcGVyYXR1cmUsIGluaXRpYWwgaHlkcmF0aW9uIGxldmVsLCBhbmQgb3JpZ2luIChsYWItcmFpc2VkIG9yIHdpbGQgY2F1Z2h0KS4gR3JvdXAtbGV2ZWwgZWZmZWN0cyBpbmNsdWRlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb25zICgkXHNpZ21hJCkgZm9yIHN0dWR5LWxldmVsIG9ic2VydmF0aW9ucyAoJFxzaWdtYV97c3R1ZHl9XjIkKSwgcGh5bG9nZW5ldGljIHJlbGF0ZWRuZXNzICgkXHNpZ21hX3twaHlsb2dlbnl9XjIkKSwgYW5kIHRoZSBjb3JyZWxhdGlvbiBhbW9uZyBzcGVjaWVzICgkXHNpZ21hX3tzcGVjaWVzfV4yJCkgYW5kIGJvZHkgbWFzcyAoJFxzaWdtYV97bG5NYXNzfV4yJCkuICRSX3ttYXJnaW5hbH1eMiQgcmVwcmVzZW50cyB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGZpeGVkIGVmZmVjdHMsIHdoaWxlICRSX3tjb25kaXRpb25hbH1eMiQgcmVwcmVzZW50cyB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGJvdGggZml4ZWQgZWZmZWN0cyBhbmQgZ3JvdXAtbGV2ZWwgZWZmZWN0cy4KCmBgYHtyIHRhYmxlUzUsIGVjaG8gPSBGQUxTRX0KIyBGaXhlZCBlZmZlY3QKZmVmIDwtIGJybXM6OmZpeGVmKHd1X21vZGVsKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSguKSAlPiUKICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiUGFyYW1ldGVyIikgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gc3RyX3JlcGxhY2UoUGFyYW1ldGVyLCAiTSIsICItIikpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9IGNhc2Vfd2hlbigKICAgIFBhcmFtZXRlciA9PSAiSW50ZXJjZXB0IiB+ICJsbiRcXGJldGFfMCQiLAogICAgUGFyYW1ldGVyID09ICJlY290eXBlRm9zc29yaWFsIiAgfiAiRm9zc29yaWFsIiwKICAgIFBhcmFtZXRlciA9PSAiZWNvdHlwZUdyb3VuZC1kd2VsbGluZyIgIH4gIkdyb3VuZC1kd2VsbGluZyIsCiAgICBQYXJhbWV0ZXIgPT0gImVjb3R5cGVTZW1pLWFxdWF0aWMiICB+ICJTZW1pLWFxdWF0aWMiLAogICAgUGFyYW1ldGVyID09ICJsbi1hc3MiICB+ICJsbk1hc3MiLAogICAgUGFyYW1ldGVyID09ICJ0cnRfdGVtcCIgIH4gIlRyZWF0bWVudCB0ZW1wZXJhdHVyZSIsCiAgICBQYXJhbWV0ZXIgPT0gImh5ZHJhdGlvbiIgIH4gIkluaXRpYWwgaHlkcmF0aW9uIiwKICAgIFBhcmFtZXRlciA9PSAib3JpZ2lud2lsZCIgIH4gIk9yaWdpbiAtIFdpbGQiLAogICAgICAgIFRSVUUgICB+IFBhcmFtZXRlcikpICU+JSAKICB0aWJibGU6OmFkZF9yb3coUGFyYW1ldGVyID0gIioqRml4ZWQgZWZmZWN0cyoqIiwgLmJlZm9yZSA9IDEpCgojIFJhbmRvbSBlZmZlY3QKcmVmIDwtIHN1bW1hcnkod3VfbW9kZWwpJHJhbmRvbSAlPiUgCiAgYmluZF9yb3dzKCkgJT4lICMgdW5saXN0CiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIlBhcmFtZXRlciIpICU+JSAKICBkcGx5cjo6c2VsZWN0KDE6NSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gYygiJFxcc2lnbWFfe3NwZWNpZXN9XjIkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkXFxzaWdtYV97bG5NYXNzfV4yJCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY29yKCRcXHNpZ21hX3tzcGVjaWVzfV4yJCwgJFxcc2lnbWFfe2xuTWFzc31eMiQpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkXFxzaWdtYV97cGh5bG9nZW55fV4yJCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3N0dWR5fV4yJCIpKSAlPiUgICAKICBkcGx5cjo6cmVuYW1lKFEyLjUgID0gNCwgCiAgICAgICAgICAgICAgICBROTcuNSA9IDUpICU+JSAKICB0aWJibGU6OmFkZF9yb3coUGFyYW1ldGVyID0gIioqR3JvdXAtbGV2ZWwgZWZmZWN0cyoqIiwgLmJlZm9yZSA9IDEpCgp3dV9sYW1iZGEgPC0gaHlwb3RoZXNpcyh3dV9tb2RlbCwgInNkX3NwZWNpZXNfcGh5bG9fX0ludGVyY2VwdF4yIC8gKHNkX3NwZWNpZXNfcGh5bG9fX0ludGVyY2VwdF4yICsgc2lnbWFeMikgPSAwIiwgY2xhc3MgPSBOVUxMKSRoeXBvdGhlc2lzICU+JSAKICBkcGx5cjo6c2VsZWN0KC1jKDEsNjo4KSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gIiRcXGxhbWJkYSQiKSAlPiUgCiAgZHBseXI6OnJlbmFtZShRMi41ICA9IENJLkxvd2VyLCAKICAgICAgICAgICAgICAgIFE5Ny41ID0gQ0kuVXBwZXIpICU+JSAKICB0aWJibGU6OmFkZF9yb3coUGFyYW1ldGVyID0gIioqUGh5bG9nZW5ldGljIHNpZ25hbCoqIiwgLmJlZm9yZSA9IDEpCgp3dV9yMiA8LSBkYXRhLmZyYW1lKFBhcmFtZXRlciA9ICIkUl97bWFyZ2luYWx9XjIkIiwKICAgICAgICAgICAgICAgICAgICAgRXN0aW1hdGUgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyh3dV9tb2RlbCkpWzIsMV0sIDQpICogMTAwLAogICAgICAgICAgICAgICAgICAgICBRMi41ICAgICA9IHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKHd1X21vZGVsKSlbMiw0XSwgNCkgKiAxMDAsCiAgICAgICAgICAgICAgICAgICAgIFE5Ny41ICAgID0gcm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMod3VfbW9kZWwpKVsyLDVdLCA0KSAqIDEwMCkgJT4lCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIkUl97Y29uZGl0aW9uYWx9XjIkIiwKICAgICAgICAgICAgICAgICAgICAgRXN0aW1hdGUgPSByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyh3dV9tb2RlbCkpWzEsMV0sIDQpICogMTAwLAogICAgICAgICAgICAgICAgICAgICBRMi41ICAgICA9IHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKHd1X21vZGVsKSlbMSw0XSwgNCkgKiAxMDAsCiAgICAgICAgICAgICAgICAgICAgIFE5Ny41ICAgID0gcm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMod3VfbW9kZWwpKVsxLDVdLCA0KSAqIDEwMCkgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipWYXJpYW5jZSoqIiwgLmJlZm9yZSA9IDEpCgojIFJlbmRlciB0YWJsZQpiaW5kX3Jvd3MoZmVmLCByZWYsIHd1X2xhbWJkYSwgd3VfcjIpICU+JSAKICByZW1vdmVfcm93bmFtZXMoKSAlPiUgCiAga25pdHI6OmthYmxlKGRpZ2l0cyA9IDIpCmBgYAoKKioqCgojIyMgRmlnLiBTNiAtICRyX2kkIG1vZGVsIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKYGBge3IgRmlnIFM2LCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTcsIGVjaG8gPSBGQUxTRX0KcmlfY2UgICAgIDwtIGJybXM6OmNvbmRpdGlvbmFsX2VmZmVjdHMocmlfbW9kZWwsIGMoImVjb3R5cGUiLCAic3RyYXRlZ3kiKSkKcmlfZWNvX2NlIDwtIGRhdGEuZnJhbWUocmlfY2VbWzFdXSkgJT4lCiAgZHBseXI6OnJlbmFtZShlc3RpbWF0ZSA9IGVzdGltYXRlX18sIGNpLmxiID0gbG93ZXJfXywgY2kudWIgPSB1cHBlcl9fKQoKcmlfZWNvX3Bsb3QgPC0gcmlfZWNvX2NlICU+JQogIGdncGxvdChhZXMoeCA9IGVjb3R5cGUsIHkgPSBleHAoZXN0aW1hdGUpKSkgKyAKICBnZ2ZvcmNlOjpnZW9tX3NpbmEoZGF0YSA9IHJlc2lzdF9kYXQgJT4lIAogICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIoc3RyYXRlZ3kgJWluJSBjKCJub25lIiwgIndhdGVyLXByb29mIikpLCAKICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBlY290eXBlLCB5ID0gcl9zX2VzdCksIGNvbG91ciA9ICIjZGVkZWRlIiwgc2l6ZSA9IDIpICsgCiAgZ2VvbV9wb2ludChhZXMoKSwgc2l6ZSA9IDQsIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gZXhwKGNpLmxiKSwgeW1heCA9IGV4cChjaS51YikpLCBzaXplID0gMC44LCB3aWR0aCA9IDAuMSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9IHNjYWxlczo6bG9nX3RyYW5zKCksIGJyZWFrcyA9IGMoMC4wMSwgMC4xLCAxLCAxMCwgMTAwLCAxMDAwKSwgbGFiZWxzID0gYygwLjAxLCAwLjEsIDEsIDEwLCAxMDAsICIxLDAwMCIpKSArCiAgeGxhYihOVUxMKSArCiAgeWxhYihleHByZXNzaW9uKGl0YWxpYygiciIpWyJpIl1+IihzIGNtIl57LTF9KiIpIikpICsKICBteXRoZW1lKCkKCnJpX3N0cmFfY2UgPC0gYXMuZGF0YS5mcmFtZShyaV9jZVtbMl1dKSAlPiUKICBkcGx5cjo6cmVuYW1lKGVzdGltYXRlID0gZXN0aW1hdGVfXywgY2kubGIgPSBsb3dlcl9fLCBjaS51YiA9IHVwcGVyX18pCgpyaV9zdHJhX3Bsb3QgPC0gcmlfc3RyYV9jZSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzdHJhdGVneSwgeSA9IGV4cChlc3RpbWF0ZSkpKSArIAogIGdnZm9yY2U6Omdlb21fc2luYShkYXRhID0gcmVzaXN0X2RhdCwgYWVzKHggPSBzdHJhdGVneSwgeSA9IHJfc19lc3QpLCBjb2xvdXIgPSAiI2RlZGVkZSIsIG1heHdpZHRoID0gMC41LCBzaXplID0gMikgKyAKICBnZW9tX3BvaW50KGFlcygpLCBzaXplID0gNCwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBleHAoY2kubGIpLCB5bWF4ID0gZXhwKGNpLnViKSksIHNpemUgPSAwLjgsIHdpZHRoID0gMC4xLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIAogIHNjYWxlX3lfY29udGludW91cyh0cmFucyA9IHNjYWxlczo6bG9nX3RyYW5zKCksIGJyZWFrcyA9IGMoMC4wMSwgMC4xLCAxLCAxMCwgMTAwLCAxMDAwKSwgbGFiZWxzID0gYygwLjAxLCAwLjEsIDEsIDEwLCAxMDAsICIxLDAwMCIpKSArCiAgeGxhYigiU3RyYXRlZ3kiKSArCiAgeWxhYihleHByZXNzaW9uKGl0YWxpYygiciIpWyJpIl1+IihzIGNtIl57LTF9KiIpIikpICsKICBteXRoZW1lKCkKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChyaV9lY29fcGxvdCwgcmlfc3RyYV9wbG90LCBucm93ID0gMiwgYWxpZ24gPSAiaCIsIGF4aXMgPSAiYnQiLCBsYWJlbHMgPSBjKCdhJywgJ2InKSkKYGBgCgoqKkZpZy4gUzYuKiogRGlmZmVyZW5jZXMgaW4gcmVzaXN0YW5jZSB0byB3YXRlciBsb3NzLCAkcl9pJCAocyBjbV4tMV4pIGJ5ICgqKmEqKikgZWNvdHlwZSBhbmQgKCoqYioqKSB3YXRlci1jb25zZXJ2aW5nIHN0cmF0ZWdpZXMuIE5vdGUsIHdoZW4gcGxvdHRpbmcgYnkgZWNvdHlwZSwgdGhlICRyX2kkIGV4Y2x1ZGVzIGJlaGF2aW91cmFsIHdhdGVyLWNvbnNlcnZpbmcgc3RyYXRlZ2llcyBzdWNoIGFzIGR1cmluZyBjb2Nvb24tZm9ybWluZyBhbmQgaW5zaWRlIGhvbGxvd3MuIE1lYW4gZXN0aW1hdGVzIMKxIDk1JSBDSSBwcmVzZW50ZWQgaW4gYmxhY2sgcG9pbnRzIGFuZCBlcnJvciBiYXJzLCB3aGlsZSByYXcgdmFsdWVzIHdlcmUgcHJlc2VudGVkIGFzIGdyZXkgcG9pbnRzLgoKKioqCgojIyMgRmlnLiBTNyAtIFdVIG1vZGVsIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKYGBge3IgRmlnIFM3LCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9My41LCBmaWcud2lkdGg9NywgZWNobyA9IEZBTFNFfQp3dV9jZSA8LSBicm1zOjpjb25kaXRpb25hbF9lZmZlY3RzKHd1X21vZGVsLCBjKCJlY290eXBlIiwgImxuTWFzcyIsICJoeWRyYXRpb24iKSkKd3VfZWNvX2NlIDwtIGRhdGEuZnJhbWUod3VfY2VbWzFdXSkgJT4lCiAgZHBseXI6OnJlbmFtZShlc3RpbWF0ZSA9IGVzdGltYXRlX18sIGNpLmxiID0gbG93ZXJfXywgY2kudWIgPSB1cHBlcl9fKQoKd3VfZWNvX2NlICU+JQogIGdncGxvdChhZXMoeCA9IGVjb3R5cGUsIHkgPSBleHAoZXN0aW1hdGUpKSkgKyAKICBnZ2ZvcmNlOjpnZW9tX3NpbmEoZGF0YSA9IHd1X2RhdCwgYWVzKHggPSBlY290eXBlLCB5ID0gbWdfaF9tZWFuKSwgY29sb3VyID0gIiNkZWRlZGUiLCBzaXplID0gMikgKyAKICBnZW9tX3BvaW50KGFlcygpLCBzaXplID0gNCwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBleHAoY2kubGIpLCB5bWF4ID0gZXhwKGNpLnViKSksIHNpemUgPSAwLjgsIHdpZHRoID0gMC4xLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zID0gc2NhbGVzOjpsb2dfdHJhbnMoKSwgYnJlYWtzID0gYygxMCwgMTAwLCAxMDAwLCAxMDAwMCwgMTAwMDAwKSwgbGFiZWxzID0gYygxMCwgMTAwLCAiMSwwMDAiLCAiMTAsMDAwIiwgIjEwMCwwMDAiKSkgKwogIHhsYWIoTlVMTCkgKwogIHlsYWIoZXhwcmVzc2lvbigiV1UifigibWcifkhbMl0qT35oXnsiLTEifSkpKSArCiAgbXl0aGVtZSgpCmBgYAoKKipGaWcuIFM3LioqIERpZmZlcmVuY2VzIGluIGN1dGFuZW91cyB3YXRlciB1cHRha2UgKG1nIEh+Mn5PIGheLTFeKSBieSBlY290eXBlLiBNZWFuIGVzdGltYXRlcyDCsSA5NSUgQ0kgcHJlc2VudGVkIGluIGJsYWNrIHBvaW50cyBhbmQgZXJyb3IgYmFycywgd2hpbGUgcmF3IHZhbHVlcyB3ZXJlIHByZXNlbnRlZCBhcyBncmV5IHBvaW50cy4gVGhlIHNpemUgb2YgdGhlIGdyZXkgcG9pbnRzIGluZGljYXRlcyBzdHVkeSBwcmVjaXNpb24gKGludmVyc2Ugb2Ygc3RhbmRhcmQgZXJyb3IpLgoKKioqCgojICpOaWNoZU1hcFIqIHstfQoKVG8gZXN0aW1hdGUgdGhlIGluZmx1ZW5jZSBvZiB3YXJtaW5nIGFuZCBkcm91Z2h0IG9uIGFjdGl2aXR5IG9mIGEgaHlwb3RoZXRpY2FsIGZyb2csIHdlIHNpbXVsYXRlZCBhIHdhdGVyIGFuZCBoZWF0IGVuZXJneSBleGNoYW5nZSBtb2RlbCAoKipGaWcuIFM4YSoqKSBhbmQgaXRzIGludGVyYWN0aW9uIHdpdGggYSBzaW11bGF0ZWQgbG9jYWwgbWljcm9jbGltYXRlIHVzaW5nIHRoZSAqTmljaGVNYXBSKiBwYWNrYWdlIFtAS2Vhcm5leTIwMTc7IEBLZWFybmV5MjAyMF0uCgohW10oRmlnIFM4IC0gRW5lcmd5IGFuZCB3YXRlciBleGNoYW5nZS5wbmcpCgoqKkZpZy4gUzguKiogU3VtbWFyeSB3YXRlciBhbmQgZW5lcmd5IGV4Y2hhbmdlIG1vZGVsIGZyb20gQFRyYWN5MTk3NiBpbnRlZ3JhdGVkIGludG8gKk5pY2hlTWFwUiogYW5kIHdhdGVyIGNvbnNlcnZpbmcgc3RyYXRlZ2llcy4gKCoqYSoqKSBTY2hlbWF0aWMgc3VtbWFyeSBvZiB0aGUgZXhjaGFuZ2VzIG9mIGVuZXJneSBhbmQgd2F0ZXIgYmV0d2VlbiBhIGZyb2cgYW5kIGl0cyBlbnZpcm9ubWVudCB1c2VkIHRvIGRldmVsb3AgdGhlIHRyYW5zaWVudC1zdGF0ZSBtb2RlbCBvZiB3YXRlciBleGNoYW5nZS4gSW4gcmVzcGVjdCB0byB3YXRlciBleGNoYW5nZSwgdGhlIG5ldCB3YXRlciBsb3NzIHJlcHJlc2VudHMgd2F0ZXIgbG9zcyBmcm9tIHJlc3BpcmF0b3J5LCBjdXRhbmVvdXMsIG9jdWxhciwgYW5kIGNsb2FjYSBldmFwb3JhdGlvbiBhcyB3ZWxsIGFzIHVyaW5hcnkgYW5kIGZhZWNhbCB3YXRlciBbQFBpcnRsZTIwMTldLiAoKipiKiopIEJlaGF2aW91cmFsLCBtb3JwaG9sb2dpY2FsLCBhbmQgcGh5c2lvbG9naWNhbCBzdHJhdGVnaWVzIGVtcGxveWVkIGJ5IGZyb2dzIG9uIGxhbmQgdG8gcmVkdWNlIHdhdGVyIGxvc3MgW0BIaWxsbWFuMjAwOV0uCgojIyBTaW11bGF0ZSB3YXRlci1jb25zZXJ2aW5nIGJlaGF2aW91cnMgey19CgpXZSB1c2VkIHRoZSBtb2R1bGFyaXplZCB2ZXJzaW9uIG9mICpOaWNoZU1hcFIq4oCZcyB2My4yLjEgZWN0b3RoZXJtIG1vZGVsIChpLmUuIGBlY3RvUl9kZXZlbGApIGFuZCBjb2RlZCBiZWhhdmlvcmFsIGZ1bmN0aW9ucyB0byBhY2NvdW50IGZvciB0aGUgaW5mbHVlbmNlIG9mIGh5ZHJhdGlvbiBvbiBhY3Rpdml0eSAoYGJlaGF2X2Z1bmN0aW9uc2AgZnVuY3Rpb24pIHdoaWNoIGNhbiBiZSBmb3VuZCBpbiB0aGUgW2JlaGF2X2Z1bmN0aW9ucy5SXShodHRwczovL2dpdGh1Yi5jb20vbmljaG9sYXN3dW56L2dsb2JhbC1mcm9nLWRyb3VnaHQvYmxvYi9tYWluL2NvZGUvYmVoYXZfZnVuY3Rpb25zLlIpIGZpbGUgb24gR2l0SHViLiAKCldoZW4gdGhlIGFuaW1hbCBpcyBub3QgYWN0aXZlIChpLmUuIGlzIGJlbG93IGdyb3VuZCksIGl0IGlzIHNpbXVsYXRlZCB0byBnbyB0byBhbiB1bmRlcmdyb3VuZCByZXRyZWF0LiBJdCBzZWxlY3RzIHRoZSBzaGFsbG93ZXN0IGRlcHRoIHdpdGggdGVtcGVyYXR1cmVzIGJldHdlZW4gVG1heCBhbmQgVG1pbi4gSWYgd2F0ZXIgPSBULCB0aGUgZnJvZyBzZWxlY3RzIHRoZSBzaGFsbG93ZXN0IG5vZGUgd2l0aCB0ZW1wZXJhdHVyZXMgYmV0d2VlbiBUbWF4IGFuZCBUbWluIGFuZCBhIHdhdGVyIHBvdGVudGlhbCA+PSAtNzIuNSwgd2hpY2ggd2FzIHJlcG9ydGVkIGFzIGEgc29pbCB3YXRlciBwb3RlbnRpYWwgZnJvbSB3aGljaCAqUmFuYSBwaXBpZW5zKiBjb3VsZCBhYnNvcmIgd2F0ZXIuIFdoZW4gdGhlIGFuaW1hbCBpcyBiZWxvd2dyb3VuZCwgaXQgcmUtaHlkcmF0ZXMgaWYgdGhlIHNvaWwgd2F0ZXIgcG90ZW50aWFsIGlzID49IC03Mi41LCBhdCBhIHJhdGUgc3BlY2lmaWVkIGluIGh5ZC5yYXRlIGFuZCBwcm9wb3J0aW9uYWwgdG8gdGhlIGxldmVsIG9mIGRlaHlkcmF0aW9uLCBmb2xsb3dpbmc6CgpcYmVnaW57ZXF1YXRpb259ClxmcmFje0h5ZF97bWF4fSAtIEh5ZF97aX19e0h5ZF97bWF4fX0gXHRpbWVzIGh5ZC5yYXRlLCAKKFwjZXE6aHlkKQpcZW5ke2VxdWF0aW9ufQogCkl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQgY3VycmVudGx5IGZyb2dzIGFyZSBub3QgcmUtaHlkcmF0aW5nIHdoZW4gYWN0aXZlIGFib3ZlZ3JvdW5kLgoKVGhlIOKAnHNraW53ZXTigJ0gdGVybSAoJHBfe3dldH0kKSBkZXRlcm1pbmVzIHRoZSBwcm9wb3J0aW9uIG9mIHRoZSB0b3RhbCBzdXJmYWNlIGFyZWEgdXNlZCBpbiB0aGUgY2FsY3VsYXRpb24gb2YgbWFzcyB0cmFuc2ZlciBvZiB3YXRlciBmcm9tIHRoZSBzdXJmYWNlLiBIZXJlLCAkcF97d2V0fSQgd2FzIGNhbGN1bGF0ZWQgZnJvbSBlbXBpcmljYWxseSBkZXJpdmVkIHNraW4gcmVzaXN0YW5jZSBmb2xsb3dpbmcgQFBpcnRsZTIwMTk6CgpcYmVnaW57ZXF1YXRpb259CnBfe3dldH0gPSBcZnJhY3sxfXtoX0QgXHRpbWVzIHJfaSArIChcZnJhY3tQX3J9e1NfY30pXlxmcmFjezJ9ezN9fSwgCihcI2VxOnB3ZXQpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkcl9pJCBpcyB0aGUgc2tpbuKAmXMgcmVzaXN0YW5jZSB0byB3YXRlciB2YXBvciB0cmFuc2ZlciAocyBtXi0xXiksICRQX3IkIGlzIHRoZSBQcmFuZHRsIG51bWJlciAoZGltZW5zaW9ubGVzcyksICRTX2MkIGlzIHRoZSBTY2htaWR0IG51bWJlciAoZGltZW5zaW9ubGVzcyksICRoX0QkIGlzIHRoZSBtYXNzIHRyYW5zZmVyIGNvZWZmaWNpZW50IChtIHNeLTFeKS4gVG8gY2FsY3VsYXRlICRwX3t3ZXR9JCwgdGhlIG1hc3MgdHJhbnNmZXIgY29lZmZpY2llbnQgKCRoX0QkKSBtdXN0IGJlIGtub3duLiBNYXNzIHRyYW5zZmVyIHJlZmVycyB0byB0aGUgbW92ZW1lbnQgb2YgYSBzdWJzdGFuY2UgdGhvdWdoIGEgZmx1aWQgaW50ZXJmYWNlLCBkcml2ZW4gYnkgY2hhbmdlcyBpbiB0aGUgY29uY2VudHJhdGlvbiBncmFkaWVudC4gVGhlIG1hc3MgdHJhbnNmZXIgY29lZmZpY2llbnQgY29udHJvbHMgdGhlIHJhdGUgb2YgZGlmZnVzaW9uIGFuZCBpcyBkZXBlbmRlbnQgb24gdmVsb2NpdHksIHRlbXBlcmF0dXJlLCBhbmQgcGh5c2ljYWwgcHJvcGVydGllcyBvZiB0aGUgaW50ZXJwaGFzZS4gU2ltaWxhciB0byB0aGUgaGVhdCB0cmFuc2ZlciBjb2VmZmljaWVudCwgdGhlIG1hc3MgdHJhbnNmZXIgY29lZmZpY2llbnQgYWxzbyBoYXMgdHdvIGNvbXBvbmVudHMgZGVyaXZlZCBmcm9tIGZyZWUgYW5kIGZvcmNlZCBjb252ZWN0aW9uLiBXZSBjb25zaWRlciBmb3JjZWQgY29udmVjdGlvbiBvbmx5IChhcyBmcmVlIGNvbnZlbnRpb24gc2hvdWxkIGJlIG5lZ2xpZ2libGUgd2l0aGluIGEgbWVhc3VyZW1lbnQgY2hhbWJlciksIGFuZCB0aGlzIGNhbiBiZSBjYWxjdWxhdGVkIGZyb20gdGhlIGhlYXQgdHJhbnNmZXIgY29lZmZpY2llbnQ6CgpcYmVnaW57ZXF1YXRpb259CmhfRCA9IChcZnJhY3toX0N9e0NfcCBcdGltZXMgXHJob30pIFx0aW1lcyAoXGZyYWN7UF9yfXtTX2N9KSBeIFxmcmFjezJ9ezN9LCAKKFwjZXE6aGQpClxlbmR7ZXF1YXRpb259Cgp3aGVyZSAkUF9yJCBpcyB0aGUgUHJhbmR0bCBudW1iZXIgKGRpbWVuc2lvbmxlc3MpLCAkU19jJCBpcyB0aGUgU2NobWlkdCBudW1iZXIgKGRpbWVuc2lvbmxlc3MpLCAkaF9DJCBpcyB0aGUgaGVhdCB0cmFuc2ZlciBjb2VmZmljaWVudCAoSiBzXi0xXiBjbV4tMl4gS14tMV4pLCAkXHJobyQgaXMgdGhlIGRlbnNpdHkgb2YgZHJ5IGFpciAoZyBjbV4tM14pLCBhbmQgJENfcCQgaXMgdGhlIHNwZWNpZmljIGhlYXQgb2YgYWlyICgxLjAxIEogZ14tMV4gS14tMV4pLgoKIyMgU2ltdWxhdGUgZHJvdWdodCBhbmQgd2FybWluZyB7LX0KCk1pY3JvY2xpbWF0ZXMgcmVwcmVzZW50IHRoZSBwaHlzaWNhbCBlbnZpcm9ubWVudHMgZXhwZXJpZW5jZWQgYnkgYW4gb3JnYW5pc20uIFRoZXkgYXJlIGEgbmVjZXNzaXR5IGZvciBtZWNoYW5pc3RpYyBuaWNoZSBtb2RlbGxpbmcgYmVjYXVzZSBpdCBpcyB0aGUgZW52aXJvbm1lbnQgZXhwZXJpZW5jZWQgYXQgdGhlIHNjYWxlIG9mIHRoZSBpbmRpdmlkdWFsIHRoYXQgbmVlZHMgdG8gYmUgcHJvdmlkZWQgdG8gdGhlIGVxdWF0aW9ucyBvZiBlbmVyZ3kgYW5kIG1hc3MgYmFsYW5jZS4gVGhlIG1pY3JvY2xpbWF0ZSBtb2RlbCB3YXMgaW1wbGVtZW50ZWQgYXMgZGVzY3JpYmVkIGJ5IEBLZWFybmV5MjAxNC4gU3BlY2lmaWNhbGx5LCBpdCB3YXMgZHJpdmVuIGJ5IGhpc3RvcmljYWwgMC4wNcKwIGdyaWQgKH41IGttKSBkYWlseSB3ZWF0aGVyIGlucHV0IGxheWVycyAoYWlyIHRlbXBlcmF0dXJlLCB2YXBvciBwcmVzc3VyZSwgd2luZCBzcGVlZCwgYW5kIGNsb3VkIGNvdmVyKS4KCldlIHNpbXVsYXRlZCBtZXRlb3JvbG9naWNhbCBkcm91Z2h0IChkZWZpbmVkIGFzIGxlc3MgdGhhbiBhdmVyYWdlIHJhaW5mYWxsKSBieSBtb2RpZnlpbmcgdGhlIGBtaWNyb19lcmE1YCBmdW5jdGlvbiBmcm9tICpOaWNoZU1hcFIqIHRvIGluY29ycG9yYXRlIHJhaW5mYWxsIChgcmFpbmZhY3RgKSBhbmQgcmVsYXRpdmUgaHVtaWRpdHkgKGByaGZhY3RgKSBkZWZpY2l0IGZhY3RvcnMuIEEgZGVmYXVsdCBmYWN0b3IgaXMgMSB3aGljaCBpcyAxMDAlIG9mIHRoZSBvcmlnaW5hbCByYWluZmFsbCBvciByZWxhdGl2ZSBodW1pZGl0eS4gQSBmYWN0b3Igb2YgMC41IG1lYW5zIDUwJSBvZiB0aGUgb3JpZ2luYWwgcmFpbmZhbGwgb3IgcmVsYXRpdmUgaHVtaWRpdHkuIFRoZSBtb2RpZmllZCBmdW5jdGlvbiBjYW4gYmUgZm91bmQgb24gdGhlIGFjY29tcGFueWluZyBHaXRIdWIgcGFnZS4KClRvIHNpbXVsYXRlIGZyb2cgYWN0aXZpdHkgdW5kZXIgZHJvdWdodCBhbmQgd2FybWluZyBzY2VuYXJpb3MsIHdlIGNvbnN0cnVjdGVkIGZvdXIgY2xpbWF0ZSBjb25kaXRpb25zIHVzaW5nIHRoZSBgbWljcm9fZXJhNWAgZnVuY3Rpb246IAoKMS4gKipjdXJyZW50IG5vcm1hbCBzY2VuYXJpbyoqIHJlcHJlc2VudGluZyB0aGUgbWVhbiBhbm51YWwgYWlyIHRlbXBlcmF0dXJlIGFuZCByYWluZmFsbCBmcm9tIDE5ODHigJMyMDEwLAoyLiAqKmN1cnJlbnQgZHJvdWdodCBzY2VuYXJpbyoqIHJlcHJlc2VudGluZyB0aGUgbWVhbiBhbm51YWwgYWlyIHRlbXBlcmF0dXJlIGZyb20gMTk4MS0yMDEwIGFuZCBhbm51YWwgcmFpbmZhbGwgYmFzZWQgb24gMjAxNy0yMDE5IGRyb3VnaHQgaW4gQXVzdHJhbGlhICgqKkZpZy4gUzkqKiksCjMuICoqd2FybWluZyBub3JtYWwgc2NlbmFyaW8qKiByZXByZXNlbnRpbmcgdGhlIOKAnGJ1c2luZXNzLWFzLXVzdWFs4oCdIHNjZW5hcmlvLCB3aGVyZSB0aGUgZ2xvYmFsIHN1cmZhY2UgdGVtcGVyYXR1cmUgaXMgZXN0aW1hdGVkIHRvIGluY3JlYXNlIGJ5IDTCsEMgYnkgMjA4MOKAkzIxMDAgd2l0aCBubyBlZmZlY3Qgb2YgZHJvdWdodCAoKzTCsEMgb25seSksIGFuZCAKNC4gKip3YXJtaW5nIGRyb3VnaHQgc2NlbmFyaW8qKiB3aXRoIGEgKzTCsEMgaW5jcmVhc2luZyBpbiBhaXIgdGVtcGVyYXR1cmUgYW5kIGFubnVhbCByYWluZmFsbCBiYXNlZCBvbiAyMDE3LTIwMTkgZHJvdWdodCBpbiBBdXN0cmFsaWEuCgpGaXJzdCwgZG93bmxvYWQgdGhlIGBtY2VyYTVgIG1pY3JvY2xpbWF0ZSBkYXRhIHRvIGEgbG9jYWwgZGlyZWN0b3J5IHRvIHJ1biB0aGUgYG1pY3JvX2VyYTVgIGZ1bmN0aW9uIGZhc3Rlci4KCmBgYHtyIG1jZXJhX3NldHVwLCBldmFsPUZBTFNFLCBlY2hvPVR9CiMgZ2V0IEVSQTUgZGF0YSB3aXRoIHBhY2thZ2UgbWNlcmE1IAojIGFzc2lnbiB5b3VyIGNyZWRlbnRpYWxzIChyZWdpc3RlciBoZXJlOiBodHRwczovL2Nkcy5jbGltYXRlLmNvcGVybmljdXMuZXUvdXNlci9yZWdpc3RlcikKdWlkICAgICAgICAgPC0gIiQkJCQkJCIKY2RzX2FwaV9rZXkgPC0gIiQkJCQkJCQkLSQkJCQtJCQkJC0kJCQkLSQkJCQkJCQkJCQkJCIKZWNtd2ZyOjp3Zl9zZXRfa2V5KHVzZXIgPSB1aWQsIGtleSA9IGNkc19hcGlfa2V5LCBzZXJ2aWNlID0gImNkcyIpCgojIGJvdW5kaW5nIGNvb3JkaW5hdGVzIChpbiBXR1M4NCAvIEVQU0c6NDMyNikKYygtNDEuMTkwLCAtMjAuMTg2KSAKeG1uIDwtIC00Mgp4bXggPC0gLTQxCnltbiA8LSAtMjEKeW14IDwtIC0yMAoKeG1uIDwtIDE1Mgp4bXggPC0gMTU0CnltbiA8LSAtMjgKeW14IDwtIC0yNgoKIyB0ZW1wb3JhbCBleHRlbnQKc3RfdGltZSA8LSBsdWJyaWRhdGU6OnltZCgiMjAxNjowMTowMSIpICMgZWFybGllc3Qgc2FtcGxpbmcgZGF0ZQplbl90aW1lIDwtIGx1YnJpZGF0ZTo6eW1kKCIyMDE4OjEyOjMxIikgIyBsYXRlc3Qgc2FtcGxpbmcgZGF0ZQoKIyBmaWxlbmFtZSBhbmQgbG9jYXRpb24gZm9yIGRvd25sb2FkZWQgLm5jIGZpbGVzCmZpbGVfcHJlZml4IDwtICJlcmE1IgpvcCA8LSAiWU9VUiBESVJFQ1RPUlkiCgojIGJ1aWxkIGEgcmVxdWVzdCAoY292ZXJpbmcgbXVsdGlwbGUgeWVhcnMpCnJlcSA8LSBtY2VyYTU6OmJ1aWxkX2VyYTVfcmVxdWVzdCh4bWluID0geG1uLCB4bWF4ID0geG14LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeW1pbiA9IHltbiwgeW1heCA9IHlteCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0X3RpbWUgICA9IHN0X3RpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRfdGltZSAgICAgPSBlbl90aW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0ZmlsZV9uYW1lID0gZmlsZV9wcmVmaXgpCgptY2VyYTU6OnJlcXVlc3RfZXJhNShyZXF1ZXN0ID0gcmVxLCB1aWQgPSB1aWQsIG91dF9wYXRoID0gb3ApCmBgYAoKTmV4dCwgcnVuIHRoZSBgbWljcm9fZXJhNWAgZnVuY3Rpb24gZm9yIHRoZSBmb3VyIHNjZW5hcmlvcyBpbiAyMDE3IChyZXByZXNlbnRpbmcgdHlwaWNhbCByYWluZmFsbCB5ZWFyKSwgYW5kIG9uZSBmb3IgMjAxOSB0byB2YWxpZGF0ZSB0aGUgb2JzZXJ2ZWQgcmFpbmZhbGwgZGF0YS4KCmBgYHtyIG1pY3JvX3J1biwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9CnNvdXJjZSgiL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0L2NvZGUvbWljcm9fZXJhNV9kcm91Z2h0LlIiKQoKbG9uZ2xhdCA8LSBjKDE1My4wOTI0OSwgLTI3LjYyMzUpICMgS2FyYXdhdGhhLCBRTEQuCgojIEN1cnJlbnQgbm9ybWFsIDIwMTcgc2NlbmFyaW8KbWljcm9fY3Vycl93ZXQgPC0gbWljcm9fZXJhNShsb2MgPSBsb25nbGF0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5zaGFkZSA9IDEsIG1pbnNoYWRlID0gMCwgIyBzaGFkZSBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFpbmZhY3QgPSAxLjIsIHJoZmFjdCA9IDEsICMgcmFpbiBhbmQgUkggcGFyYW1ldGVycwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcm0gPSAwLCAjIGN1cnJlbnQgY2xpbWF0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdGFydCA9ICIwMS8wMS8yMDE3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZpbmlzaCA9ICIzMS8xMi8yMDE3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGF0aWFsID0gJy9Vc2Vycy9uaWNob2xhc3d1L0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLVdlc3Rlcm5TeWRuZXlVbml2ZXJzaXR5L0Ryb3VnaHQgcHJvamVjdC9TcGF0aWFsIGRhdGEva2FyYXdhdGhhL2VyYTUnLCAjIGNoYW5nZSB0byB5b3VyIGxvY2F0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZSA9IDApCgojIEN1cnJlbnQgZHJ5IDIwMTcgc2NlbmFyaW8KbWljcm9fY3Vycl9kcnkgPC0gbWljcm9fZXJhNShsb2MgPSBsb25nbGF0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5zaGFkZSA9IDEsIG1pbnNoYWRlID0gMCwgIyBzaGFkZSBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFpbmZhY3QgPSAwLjUsIHJoZmFjdCA9IDAuMSwgIyByYWluIGFuZCBSSCBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FybSA9IDAsICMgY3VycmVudCBjbGltYXRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0YXJ0ID0gIjAxLzAxLzIwMTciLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZmluaXNoID0gIjMxLzEyLzIwMTciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYXRpYWwgPSAnL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0L1NwYXRpYWwgZGF0YS9rYXJhd2F0aGEvZXJhNScsICMgY2hhbmdlIHRvIHlvdXIgbG9jYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYXZlID0gMCkKCiMgV2FybWluZyBub3JtYWwgMjAxNyBzY2VuYXJpbwptaWNyb193YXJtX3dldCA8LSBtaWNyb19lcmE1KGxvYyA9IGxvbmdsYXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bnNoYWRlID0gMSwgbWluc2hhZGUgPSAwLCAjIHNoYWRlIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYWluZmFjdCA9IDEuMiwgcmhmYWN0ID0gMSwgIyByYWluIGFuZCBSSCBwYXJhbWV0ZXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhcm0gPSA0LCAjIGZ1dHVyZSBjbGltYXRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdGFydCA9ICIwMS8wMS8yMDE3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRmaW5pc2ggPSAiMzEvMTIvMjAxNyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYXRpYWwgPSAnL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0L1NwYXRpYWwgZGF0YS9rYXJhd2F0aGEvZXJhNScsICMgY2hhbmdlIHRvIHlvdXIgbG9jYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZSA9IDApCgojIFdhcm1pbmcgZHJ5IDIwMTcgc2NlbmFyaW8gKHNpbXVsYXRpbmcgMjAxOSBkcm91Z2h0KQptaWNyb193YXJtX2RyeSA8LSBtaWNyb19lcmE1KGxvYyA9IGxvbmdsYXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bnNoYWRlID0gMSwgbWluc2hhZGUgPSAwLCAjIHNoYWRlIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYWluZmFjdCA9IDAuNSwgcmhmYWN0ID0gMC4xLCAjIHJhaW4gYW5kIFJIIHBhcmFtZXRlcnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJtID0gNCwgIyBmdXR1cmUgY2xpbWF0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdGFydCA9ICIwMS8wMS8yMDE3IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGZpbmlzaCA9ICIzMS8xMi8yMDE3IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGF0aWFsID0gJy9Vc2Vycy9uaWNob2xhc3d1L0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLVdlc3Rlcm5TeWRuZXlVbml2ZXJzaXR5L0Ryb3VnaHQgcHJvamVjdC9TcGF0aWFsIGRhdGEva2FyYXdhdGhhL2VyYTUnLCAjIGNoYW5nZSB0byB5b3VyIGxvY2F0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F2ZSA9IDApCgojIFNpbXVsYXRlIHJhaW5mYWxsIGZvciAyMDE5IGRyb3VnaHQKYWN0X2RyeSA8LSBtaWNyb19lcmE1KGxvYyA9IGxvbmdsYXQsIAogICAgICAgICAgICAgICAgICAgICAgcnVuc2hhZGUgPSAxLCBtaW5zaGFkZSA9IDAsICMgc2hhZGUgcGFyYW1ldGVycwogICAgICAgICAgICAgICAgICAgICAgd2FybSA9IDAsICMgY3VycmVudCBjbGltYXRlCiAgICAgICAgICAgICAgICAgICAgICBkc3RhcnQgPSAiMDEvMDEvMjAxOSIsIAogICAgICAgICAgICAgICAgICAgICAgZGZpbmlzaCA9ICIzMS8xMi8yMDE5IiwKICAgICAgICAgICAgICAgICAgICAgIHNwYXRpYWwgPSAnL1VzZXJzL25pY2hvbGFzd3UvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtV2VzdGVyblN5ZG5leVVuaXZlcnNpdHkvRHJvdWdodCBwcm9qZWN0L1NwYXRpYWwgZGF0YS9rYXJhd2F0aGEvZXJhNScsICMgY2hhbmdlIHRvIHlvdXIgbG9jYXRpb24KICAgICAgICAgICAgICAgICAgICAgIHNhdmUgPSAwKQpgYGAKClRvIHZlcmlmeSBvdXIgbWljcm9jbGltYXRlIG1vZGVscywgd2UgcGxvdHRlZCB0aGUgc2ltdWxhdGVkIHRoZSBkYWlseSByYWluZmFsbCBmb3IgMjAxNyAocmVwcmVzZW50aW5nIHR5cGljYWwgcmFpbmZhbGwpIGFuZCAyMDE5IChoaXN0b3JpY2FsIGRyb3VnaHQpIHdpdGggdGhlIFtvYnNlcnZlZCBkYWlseSByYWluZmFsbCBdKGh0dHA6Ly93d3cuYm9tLmdvdi5hdS9jbGltYXRlL2Ryb3VnaHQva25vd2xlZGdlLWNlbnRyZS9wcmV2aW91cy1kcm91Z2h0cy5zaHRtbCkgaW4gQXVzdHJhbGlhIGZvciB0aGUgZm9sbG93aW5nIGxvY2F0aW9uOiBLYXJhd2F0aGEsIFNvdXRoZWFzdCBRdWVlbnNsYW5kLCBBdXN0cmFsaWEgKDE1My4wOTI0OSwgLTI3LjYyMzUpLiBLYXJhd2F0aGEgcHJvdmlkZXMgYSBnb29kIGNhc2Ugc3R1ZHkgYmVjYXVzZSB0aGVyZSBhcmUgbWFueSBlY290eXBlcyBmb3VuZCBpbiB0aGlzIGxvY2F0aW9uOiBncm91bmQtZHdlbGxpbmcgKGUuZy4gKlJoaW5lbGxhIG1hcmluYSopLCBhcmJvcmVhbCAoZS5nLiAqTGl0b3JpYSBjYWVydWxlYSopLCBmb3Nzb3JpYWwgKGUuZy4gKkN5Y2xvcmFuYSBhbGJvZ3V0dGF0YSopLCBzZW1pLWFxdWF0aWMgKGUuZy4gKkxpdG9yaWEgbmFzdXRhKiksIGFuZCB0aGlzIGFyZWEgaGFzIGV4cGVyaWVuY2VkIGRyb3VnaHQgcmVjZW50bHkgKDIwMTkpLiBXZSBleHRyYWN0ZWQgcmFpbmZhbGwgZGF0YSBmcm9tIGEgd2VhdGhlciBzdGF0aW9uIG5leHQgdG8gS2FyYXdhdGhhIHdoaWNoIGV4cGVyaWVuY2VkICJ2ZXJ5IG11Y2ggYmVsb3cgYXZlcmFnZSIgcmFpbmZhbGwgZnJvbSB0aGUgQXVzdHJhbGlhbiBCdXJlYXUgb2YgTWV0ZW9yb2xvZ3kuCgpgYGB7ciBGaWcgUzksIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD0zLjUsIGZpZy53aWR0aD04fQojIExvYWQgb2JzZXJ2ZWQgcmFpbmZhbGwgZm9yIDIwMTkKb2JzX3JhaW5mYWxsIDwtIHJlYWQuY3N2KGZpbGUucGF0aChkYXRhX3BhdGgsICJvYnNfcmFpbmZhbGwuY3N2IikpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJET1kiKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRhdGUgPSBsdWJyaWRhdGU6Om1ha2VfZGF0ZSh5ZWFyID0gMjAxOSwgbW9udGggPSBtb250aF9udW0sIGRheSA9IGRheSkpCgojIE1lcmdlIG9ic2VydmVkIGFuZCBwcmVkaWN0ZWQgcmFpbmZhbGwgdG9nZXRoZXIKbW9kZWxfcmFpbl93ZXQgPC0gYXMuZGF0YS5mcmFtZShtaWNyb19jdXJyX3dldCRSQUlORkFMTCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oIkRPWSIpICU+JQogIHJlbmFtZShyYWluZmFsbF9tbSA9ICJtaWNyb19jdXJyX3dldCRSQUlORkFMTCIpICU+JQogIG1lcmdlKG9ic19yYWluZmFsbCwgYnkgPSAiRE9ZIiwgYWxsLnggPSBUUlVFKQoKbW9kZWxfMjAxOSA8LSBhcy5kYXRhLmZyYW1lKGFjdF9kcnkkUkFJTkZBTEwpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJET1kiKSAlPiUKICByZW5hbWUocmFpbmZhbGxfbW0gPSAiYWN0X2RyeSRSQUlORkFMTCIpICU+JQogIG1lcmdlKG9ic19yYWluZmFsbCwgYnkgPSAiRE9ZIiwgYWxsLnggPSBUUlVFKQoKIyAyMDE5IGRyb3VnaHQgdmFsaWRhdGUKcmFpbl9kcnlfcGxvdCA8LSBtb2RlbF8yMDE5ICU+JQogIGdncGxvdCgpICsKICBnZW9tX2xpbmUoYWVzKHggPSBET1ksIHkgPSBrYXJhd2F0aGFfMTkpLCBjb2xvdXIgPSAiZ3JleSIpICsKICBnZW9tX2xpbmUoYWVzKHggPSBET1ksIHkgPSByYWluZmFsbF9tbSksIGNvbG91ciA9ICJyZWQiLCBhbHBoYSA9IDAuNSkgKwogIGxhYnMoeCA9ICJEYXkgb2YgdGhlIHllYXIiLCB5ID0gZXhwcmVzc2lvbigiRGFpbHkgcmFpbmZhbGwgKG1tIGRheSJeeyItMSJ9KiIpIikpICsKICBnZ3RpdGxlKCIyMDE5IERyb3VnaHQiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbSA9IGMoMCwgMTAwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMzY1LCA1MCksIGV4cGFuZCA9IGMoMCwgMCkpICsgCiAgbXl0aGVtZSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCgojIDIwMTcgbm9ybWFsIHZhbGlkYXRlCnJhaW5fd2V0X3Bsb3QgPC0gbW9kZWxfcmFpbl93ZXQgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fbGluZShhZXMoeCA9IERPWSwgeSA9IGthcmF3YXRoYV8xNyksIGNvbG91ciA9ICJncmV5IikgKwogIGdlb21fbGluZShhZXMoeCA9IERPWSwgeSA9IHJhaW5mYWxsX21tKSwgY29sb3VyID0gInJlZCIsIGFscGhhID0gMC41KSArCiAgbGFicyh4ID0gIkRheSBvZiB0aGUgeWVhciIsIHkgPSBleHByZXNzaW9uKCJEYWlseSByYWluZmFsbCAobW0gZGF5Il57Ii0xIn0qIikiKSkgKwogIGdndGl0bGUoIjIwMTcgTm9ybWFsIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW0gPSBjKDAsIDEwMCksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDM2NSwgNTApLCBleHBhbmQgPSBjKDAsIDApKSArIAogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQoKY293cGxvdDo6cGxvdF9ncmlkKHJhaW5fd2V0X3Bsb3QsIHJhaW5fZHJ5X3Bsb3QsIG5jb2wgPSAyKQpgYGAKCioqRmlnLiBTOS4qKiBTaW11bGF0ZWQgcmFpbmZhbGwgZnJvbSB0aGUgYG1pY3JvX2VyYTVgIGZ1bmN0aW9uIChyZWQpIGFuZCB0aGUgb2JzZXJ2ZWQgcmFpbmZhbGwgZm9yIEthcmF3YXRoYSwgUUxEIGZyb20gdGhlIEF1c3RyYWxpYW4gQnVyZWF1IG9mIE1ldGVvcm9sb2d5IChncmV5KS4gVGhlIHRvdGFsIHllYXJseSBvYnNlcnZlZCByYWluZmFsbApmb3IgMjAxNyB3YXMgYXMgKipgciBzdW0obW9kZWxfcmFpbl93ZXQka2FyYXdhdGhhXzE3KWAgbW0qKiwgYW5kIHRoZSB0b3RhbCBzaW11bGF0ZWQgeWVhcmx5IHJhaW5mYWxsIGZyb20gKk5pY2hlTWFwUiogd2FzICoqYHIgc3VtKG1vZGVsX3JhaW5fd2V0JHJhaW5mYWxsX21tKWAgbW0qKi4gVGhlIHRvdGFsIHllYXJseSBvYnNlcnZlZCByYWluZmFsbCBmb3IgdGhlIDIwMTkgZHJvdWdodCB3YXMgKipgciBzdW0obW9kZWxfMjAxOSRrYXJhd2F0aGFfMTkpYCBtbSoqLCBhbmQgdGhlIHRvdGFsIHNpbXVsYXRlZCB5ZWFybHkgcmFpbmZhbGwgZnJvbSAqTmljaGVNYXBSKiB3YXMgKipgciBzdW0obW9kZWxfMjAxOSRyYWluZmFsbF9tbSlgIG1tKiouIFRoZSBhdmVyYWdlIHllYXJseSByYWluZmFsbCBhY3Jvc3MgMTk4MS0yMDEwIGlzIGFyb3VuZCAqKjExMDAgbW0qKiBwZXIgeWVhci4KCiMjIFNpbXVsYXRlIGFjdGl2aXR5IHstfQoKV2Ugc2ltdWxhdGVkIHRoZSBwb3RlbnRpYWwgbnVtYmVyIG9mIGhvdXJzIGZvciBhY3Rpdml0eSBpbiBhIHllYXIgKCR0X3thY3R9JCkgd2hpY2ggcmVwcmVzZW50cyB0aGUgc3VpdGFibGUgdGhlcm1hbCBhbmQgaHlkcmljIGNvbmRpdGlvbnMgZm9yIHRoZSBhbmltYWwgdG8gbW92ZSBiZXlvbmQgdGhlaXIgcmV0cmVhdCB0byBlaXRoZXIgY2F0Y2ggcHJleSBvciBmaW5kaW5nIG1hdGVzIFtAS2Vhcm5leTIwMjBdLiBUaGUgdGhlcm1vcmVndWxhdG9yeSBhbmQgaHlkcm9yZWd1bGF0b3J5IHNlcXVlbmNlIGluIHRoZSBtb2RlbCBhc3N1bWVzIHRoYXQgZnJvZ3Mgd2lsbCBvbmx5IGJlIOKAmGFjdGl2ZeKAmSAoaS5lLiBtb3ZpbmcgYmV5b25kIHRoZWlyIHJldHJlYXQsIGNhdGNoaW5nIHByZXksIGZpbmRpbmcgbWF0ZXMpIGJldHdlZW4gdGhlIG1pbmltdW0gYW5kIG1heGltdW0gYm9keSB0ZW1wZXJhdHVyZSB0aHJlc2hvbGRzIGZvciBmb3JhZ2luZywgYFRtaW5gIGFuZCBgVG1heGAgKMKwQyksIGFuZCB0aGUgbWluaW11bSB0b2xlcmF0ZWQgaHlkcmF0aW9uLCBgbWluLmh5ZGAgKCUpLiBJbiBhZGRpdGlvbiwgaWYgYHdhdGVyLmFjdCA9IFRgLCB0aGUgZnJvZyB3aWxsIG9ubHkgYmUgYWN0aXZlIGlmIHRlbXBlcmF0dXJlcyBhcmUgd2l0aGluIHRoZSBzdWl0YWJsZSB0ZW1wIHJhbmdlLCBhbmQgdGhlIGZyb2cgaXMgbm90IGV4cGVjdGVkIHRvIGdvIGJlbG93IGFsbG93ZWQgaHlkcmF0aW9uIGxldmVscyAoZS5nLiBpZiAlaHlkcmF0aW9uIGlzIG5vdCBiZWxvdyBgbWluLmh5ZGApLgoKVG8gZXN0aW1hdGUgdGhlIHBvdGVudGlhbCAkdF97YWN0fSQgZm9yIG9uZSB5ZWFyLCB3ZSBzaW11bGF0ZWQgdGhlIGh5cG90aGV0aWNhbCBmcm9nIHRvIGJlIGFjdGl2ZSBkdXJpbmcgdGhlIGRheSBhbmQgbmlnaHQgKDI0IGhvdXJzKS4gV2hpbGUgbW9zdCBmcm9ncyBhcmUgbm9jdHVybmFsLCB0aGVyZSBhcmUgc29tZSBmcm9nIHNwZWNpZXMgZm91bmQgbW92aW5nIGR1cmluZyB0aGUgZGF5LiBUaGUgd2F0ZXIgaHlkcmljIHBhcmFtZXRlcnMgKGUuZy4gc2tpbiByZXNpc3RhbmNlLCB3YXRlciB1cHRha2UgcmF0ZSwgZGVoeWRyYXRpb24gdG9sZXJhbmNlKSB3ZXJlIGJhc2VkIG9uIHRoZSBhdmVyYWdlIHZhbHVlcyBvZiB0aGUgZGF0YXNldCBjb2xsZWN0ZWQgZnJvbSB0aGUgUFJJU01BIHNlYXJjaC4gVGhlIHRoZXJtYWwgcGFyYW1ldGVycyAobWluaW11bSBhbmQgbWF4aW11bSBmb3JhZ2luZyBhbmQgY3JpdGljYWwgdGVtcGVyYXR1cmUpIHdlcmUgYmFzZWQgb24gKlJoaW5hbGxhIG1hcmluYSogd2hpY2ggaGFzIGJlZW4gdmVyaWZpZWQgaW4gQEtlYXJuZXkyMDA4LgoKVGhyZWUgd2F0ZXItc2F2aW5nIHN0cmF0ZWdpZXMgd2VyZSBjb25zdHJ1Y3RlZCB0byBicm9hZGx5IHJlZmxlY3QgZWFjaCBlY290eXBlIHRoYXQgdXNlIGVpdGhlciBiZWhhdmlvdXJhbCBzdHJhdGVnaWVzIHN1Y2ggYXMgbWljcm9oYWJpdGF0IHNlbGVjdGlvbiwgb3IgcGh5c2lvbG9naWNhbCBzdHJhdGVnaWVzIHN1Y2ggYXMgaW5jcmVhc2VkIHNraW4gcmVzaXN0YW5jZSBvciBza2luIHRoaWNrbmVzcyAoKipUYWJsZSBTNSoqKS4gRm9yIGV4YW1wbGUsIG1hbnkgYW1waGliaWFucyAoZXNwaWNhbGx5IGFyaWQgc3BlY2lhbGlzdCkgc2VlayBvciBidXJyb3cgdW5kZXJncm91bmQgdG8gcmVndWxhdGUgYm9keSB0ZW1wZXJhdHVyZSBhbmQgd2F0ZXIgYmFsYW5jZSB3aXRob3V0IGV4aGliaXRpbmcgdGhpY2tlciBza2luIG9yIGhpZ2hlciBza2luIHJlc2lzdGFuY2UuIFRoaXMgaXMgYmVjYXVzZSB1bmRlcmdyb3VuZCBidXJyb3dzIGFyZSBnZW5lcmFsbHkgY29vbGVyLCBsZXNzIHZhcmllZCB0ZW1wZXJhdHVyZSBmbHVjdHVhdGlvbiwgYW5kIG1vcmUgbW9pc3QgcmVsYXRpdmUgdG8gdGhlIHN1cmZhY2UgY2xpbWF0ZS4gCgoqKlRhYmxlIFM1LioqIE1vZGlmaWVkIHBhcmFtZXRlcnMgZm9yIHRoZSBgc2ltLmVjdG9gIGZ1bmN0aW9uIGZvciBlYWNoIGh5cG90aGV0aWNhbCBmcm9nIG1vZGVsLiBUaGUgc2tpbiByZXNpc3RhbmNlIHZhbHVlcyB3ZXJlIGJhc2VkIG9uIHRoZSBhdmVyYWdlIGVtcGlyaWNhbCBtZWFzdXJlbWVudHMgZm9yIGEgdHlwaWNhbCBmcm9nIGFuZCBhIHdhdGVycHJvb2YgZnJvZyBpbiB0aGUgbWV0YS1hbmFseXNpcy4gU2VlayBzaGFkZSByZXByZXNlbnRzIG1pY3JvY2xpbWF0ZSBzaW11bGF0ZWQgdW5kZXIgc2hhZGVkIGNvbmRpdGlvbnMgKDAtOTAlIHNoYWRlKS4gUmV0cmVhdCB1bmRlcmdyb3VuZCByZXByZXNlbnRzIHRoZSBhYmlsaXR5IGZvciB0aGUgZnJvZyB0byBzZWVrIHN1aXRhYmxlIG1pY3JvY2xpbWF0ZXMgdW5kZXJncm91bmQuIENhbiBjbGltYiByZXByZXNlbnRzIHRoZSBhYmlsaXR5IGZvciB0aGUgZnJvZyB0byBzZWVrIHN1aXRhYmxlIG1pY3JvY2xpbWF0ZXMgYWJvdmUgZ3JvdW5kIGxldmVsIChlLmcuIHRyZWVzLCBjbGlmZnMpLiBOb3RlLCBmcm9ncyBhcmUgbm90IGFjdGl2ZSB3aGVuIHVuZGVyZ3JvdW5kLCBhbmQgd2F0ZXIgdXB0YWtlIG9ubHkgb2NjdXJzIGR1cmluZyBpbmFjdGl2aXR5LgoKYGBge3IgdGFibGUgUzUsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmRhdGEuZnJhbWUoc3RyYXRlZ3kgPSBjKCJTaGFkZSBvbmx5IiwgIldhdGVycHJvb2YiLCJGb3Nzb3JpYWwiKSwgCiAgICAgICAgICAgc2tpbiA9IGMoIkxvdyIsICJIaWdoIiwgIkxvdyIpLAogICAgICAgICAgIHNoYWRlID0gYygiWWVzIiwgIlllcyIsICJZZXMiKSwKICAgICAgICAgICB1bmRlcmdyb3VuZCA9IGMoIk5vIiwgIk5vIiwgIlllcyIpLAogICAgICAgICAgIGNsaW1iID0gYygiTm8iLCAiWWVzIiwgIk5vIiksCiAgICAgICAgICAgZWNvdHlwZSA9IGMoIkdyb3VuZC1kd2VsbGluZyIsICJBcmJvcmVhbCIsICJGb3Nzb3JpYWwiKSkgJT4lCiAga25pdHI6OmthYmxlKGNvbC5uYW1lcyA9IGMoIldhdGVyLXNhdmluZyBzdHJhdGVneSIsICJTa2luIHJlc2lzdGFuY2UiLCAiU2VlayBzaGFkZT8iLCAiUmV0cmVhdCB1bmRlcmdyb3VuZD8iLCAiQ2FuIGNsaW1iPyIsICJFY290eXBlIikpIApgYGAKCkl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQgd2UgZm9jdXMgb25seSBvbiB0aGUgZGlyZWN0IGVmZmVjdHMgb2YgZW52aXJvbm1lbnRhbCBjaGFuZ2Ugb24gd2F0ZXIgYnVkZ2V0cyBieSBwcmVkaWN0aW5nIGNoYW5nZXMgaW4gRVdMIHJhdGVzLiBUaGUgY29uY2x1c2lvbnMgd2UgZHJhdyBkbyBub3QgYWNjb3VudCBmb3IgdGhlIGluZGlyZWN0IGVmZmVjdHMgb2YgZW52aXJvbm1lbnRhbCBjaGFuZ2Ugb24gd2F0ZXIgYnVkZ2V0cywgc3VjaCBhcyBwb3RlbnRpYWwgY2hhbmdlcyB0byB0aGVybWFsIHRvbGVyYW5jZSBhcyBhIHJlc3VsdCBvZiBkZWh5ZHJhdGlvbiwgb3IgdGhlIHRoZXJtb3JlZ3VsYXRvcnkgZGlmZmljdWx0aWVzIHRoYXQgbWF5IGFyaXNlIGFzIGEgcmVzdWx0IG9mIGhhYml0YXQgbW9kaWZpY2F0aW9uLgoKYGBge3IgZnJvZ19zaW0sIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPVRSVUUsIHJlc3VsdHM9ImhpZGUifQpzb3VyY2UoIi9Vc2Vycy9uaWNob2xhc3d1L0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLVdlc3Rlcm5TeWRuZXlVbml2ZXJzaXR5L0Ryb3VnaHQgcHJvamVjdC9jb2RlL2JlaGF2X2Z1bmN0aW9ucy5SIikKIyBDb25zdHJ1Y3QgZnJvZyBtb2RlbAojIGNvbXB1dGUgdGhlIGhlYXQgZXhjaGFuZ2UgYnkgY29udmVjdGlvbiAoZXh0cmFjdCBtYXNzIHRyYW5zZmVyIGNvZWZmaWNpZW50LCBQcmFuZHRsIG51bWJlciBhbmQgU2NobWlkdCBudW1iZXIpCkNPTlZfb3V0IDwtIE5pY2hlTWFwUjo6Q09OVl9FTkRPKFRTICAgICA9IDE5LCAjIHNraW4gdGVtcGVyYXR1cmUgKMKwQykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEVOViAgID0gMjAsICMgZmx1aWQgdGVtcGVyYXR1cmUgKMKwQykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0hBUEUgID0gNCwgIyA0IGlzIGVsbGlwc29pZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVVJGQVIgPSBtZWFuKHJlc2lzdF9kYXQkZG9yc19TQV9jbTIsIG5hLnJtID0gVFJVRSkgLyAxMDAwMCwgICMgc3VyZmFjZSBhcmVhIGZvciBjb252ZWN0aW9uLCBtMgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTFRZUEUgPSAwLCAjIGZsdWlkIHR5cGU6IDAgPSBhaXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVSVFNUID0gMCwgIyB0ZXN0IG9mIHByZXNlbmNlIG9mIGZ1ciAobGVuZ3RoIHggZGlhbWV0ZXIgeCBkZW5zaXR5IHggZGVwdGgpICgtKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEICAgICAgPSBtZWFuKHJlc2lzdF9kYXQkRCwgbmEucm0gPSBUUlVFKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRGQSAgICA9IDIwLCAjIGluaXRpYWwgZnVyL2FpciBpbnRlcmZhY2UgdGVtcGVyYXR1cmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkVMICAgID0gbWVhbihyZXNpc3RfZGF0JGFpcmZsb3dfY21fcywgbmEucm0gPSBUUlVFKSAvIDEwMCwgIyB3aW5kIHNwZWVkIChtL3MpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFpGVVIgICA9IDAsICMgZnVyIGRlcHRoLCBtZWFuIChtKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCUCAgICAgPSAxMDEzMjUsICMgYmFyb21ldHJpYyBwcmVzc3VyZSBhdCBzZWEgbGV2ZWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUxFViAgID0gMCkgIyBlbGV2YXRpb24gKG0pCgojIGJhc2ljIHBhcmFtZXRlcnMgZm9yIDMwIGcgZnJvZwpXd19nICAgICAgICAgPC0gZXhwKG1lYW4obG9nKHJhd19kYXQkbWVhbl9tYXNzX2cpLCBuYS5ybSA9IFRSVUUpKSAjIGdlb21ldHJpYyBtZWFuIHdldCB3ZWlnaHQgb2YgYW5pbWFsIChnKSwgYWNjb3VudCBmb3IgdW5ldmVuIGRpc3RyaWJ1dGlvbgpyX3NfbG93ICAgICAgPC0gcmVzaXN0X2RhdCAlPiUgZHBseXI6OmZpbHRlcihzdHJhdGVneSA9PSAibm9uZSIpICU+JSBkcGx5cjo6c2VsZWN0KHJfc19lc3QpICMgc2tpbiByZXNpc3RhbmNlCnBjdF93ZXRfaGlnaCA8LSAxIC8gKENPTlZfb3V0WzVdICogbWVhbihyX3NfbG93JHJfc19lc3QsIG5hLnJtID0gVFJVRSkgKyAoQ09OVl9vdXRbMTFdIC8gQ09OVl9vdXRbMTNdKSBeIDAuNjY2NjY2NikgKiAxMDAgICMgJSBvZiBzdXJmYWNlIGFyZWEgYWN0aW5nIGFzIGEgZnJlZS13YXRlciBleGNoYW5nZXIgKFBpcnRsZSBldCBhbCAyMDE3KQoKIyBwYXJhbWV0ZXJzIGZvciBhIHdhdGVyLXByb29mIGZyb2cKcl9zX2hpZ2ggICAgPC0gcmVzaXN0X2RhdCAlPiUgZHBseXI6OmZpbHRlcihzdHJhdGVneSA9PSAid2F0ZXItcHJvb2YiKSAlPiUgZHBseXI6OnNlbGVjdChyX3NfZXN0KSAjIHNraW4gcmVzaXN0YW5jZQpwY3Rfd2V0X2xvdyA8LSAxIC8gKENPTlZfb3V0WzVdICogbWF4KHJfc19oaWdoJHJfc19lc3QsIG5hLnJtID0gVFJVRSkgKyAoQ09OVl9vdXRbMTFdIC8gQ09OVl9vdXRbMTNdKSBeIDAuNjY2NjY2NikgKiAxMDAgIyAlIG9mIHN1cmZhY2UgYXJlYSBhY3RpbmcgYXMgYSBmcmVlLXdhdGVyIGV4Y2hhbmdlciAoUGlydGxlIGV0IGFsIDIwMTcpCgojIFRoZXJtYWwgdHJhaXRzIGJhc2VkIG9uIFJoaW5lbGxhIG1hcmluYQpUbWluICAgPC0gMTMuNyAjIG1pbmltdW0gVGIgYXQgd2hpY2ggYWN0aXZpdHkgb2NjdXJzIChLZWFybmV5IGV0IGFsIDIwMDgpClRtYXggICA8LSAzMC40ICMgbWF4aW11bSBUYiBhdCB3aGljaCBhY3Rpdml0eSBvY2N1cnMgKEtlYXJuZXkgZXQgYWwgMjAwOCkKI1RfcHJlZiA8LSAyNCAjIHByZWZlcnJlZCBUYiAoS2Vhcm5leSBldCBhbCAyMDA4KQpDVG1heCAgPC0gMzcgIyBjcml0aWNhbCB0aGVybWFsIG1pbmltdW0gKGFmZmVjdHMgY2hvaWNlIG9mIHJldHJlYXQpIFRyYWN5IGV0IGFsIDIwMTIKQ1RtaW4gIDwtIDggIyBjcml0aWNhbCB0aGVybWFsIG1heGltdW0gKGFmZmVjdHMgY2hvaWNlIG9mIHJldHJlYXQpIEtvbGJlIGV0IGFsIDIwMTAsIE1jQ2FubiBldCBhbCAyMDE0CgojIFdhdGVyIGJhbGFuY2UgdHJhaXRzCm1pbl9oeWQgPC0gODAgIyBtaW5pbXVtIHRvbGVyYXRlZCBoeWRyYXRpb24gYmVmb3JlIGFjdGl2aXR5IGRlY2xpbmVzICglIG9mIGZ1bGx5IGh5ZHJhdGVkIGFuaW1hbHMpCmh5ZC5kZWF0aCA8LSA1MCAjIG1pbmltdW0gdG9sZXJhdGVkIGh5ZHJhdGlvbiBiZWZvcmUgZGVhdGggKCUgb2YgZnVsbHkgaHlkcmF0ZWQgYW5pbWFscykKd3VfcmF0ZSA8LSB3dV9kYXQgJT4lIGRwbHlyOjpmaWx0ZXIoc3RyYXRlZ3kgPT0gIm5vbmUiKSAlPiUgZHBseXI6OnNlbGVjdChtZ19oX21lYW4pCmh5ZF9yYXRlIDwtIGV4cChtZWFuKGxvZyh3dV9yYXRlJG1nX2hfbWVhbiksIG5hLnJtID0gVFJVRSkpIC8gMTAwMCAjIGdlb21ldHJpYyBtZWFuIHJlaHlkcmF0aW9uIHJhdGUgKGcvaCksIGFjY291bnQgZm9yIHVuZXZlbiBkaXN0cmlidXRpb24KIyBkZXBlbmRzIG9uIGN1cnJlbnQgYW5kIG1heCBoeWRyYXRpb24gbGlrZSB0aGlzOiBoeWQucmF0ZSAqICgoaHlkIC0gaHlkLmN1cnJlbnQpIC8gaHlkKQoKIyBiZWhhdiA9ICdkaXVybmFsJywgJ25vY3R1cm5hbCcgb3IgJ2JvdGgnCiMgd2F0ZXI7IGRvZXMgdGhlIGZyb2cgc2VsZWN0IGRlcHRoIGFjY29yZGluZyB0byB3YXRlciBwb3RlbnRpYWw/IChUUlVFIG9yIEZBTFNFKQojIHdhdGVyLmFjdDsgZG9lcyB0aGUgYWN0aXZpdHkgZGVwZW5kIG9uIHdhdGVyIGxvc3M/IChUUlVFIG9yIEZBTFNFKQoKIyBTSEFERSBNT0RFTApzaGFkX2N1cnJfd2V0X21vZCA8LSBzaW0uZWN0byhtaWNyb19jdXJyX3dldCwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gRkFMU0UsIGNsaW1iID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2hpZ2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IEZBTFNFLCB3YXRlci5hY3QgPSBUUlVFKQoKc2hhZF9jdXJyX2RyeV9tb2QgPC0gc2ltLmVjdG8obWljcm9fY3Vycl9kcnksIFd3X2cgPSBXd19nLCBzaGFwZSA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbWF4ID0gVG1heCwgVG1pbiA9IFRtaW4sIENUbWluID0gQ1RtaW4sIENUbWF4ID0gQ1RtYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaGF2ID0gJ2JvdGgnLCBpbi5zaGFkZSA9IFRSVUUsIGJ1cnJvdyA9IEZBTFNFLCBjbGltYiA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uaHlkID0gbWluX2h5ZCwgaHlkLmRlYXRoID0gaHlkLmRlYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeWQucmF0ZSA9IGh5ZF9yYXRlLCBwY3Rfd2V0ID0gcGN0X3dldF9oaWdoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2F0ZXIgPSBGQUxTRSwgd2F0ZXIuYWN0ID0gVFJVRSkKCnNoYWRfd2FybV93ZXRfbW9kIDwtIHNpbS5lY3RvKG1pY3JvX3dhcm1fd2V0LCBXd19nID0gV3dfZywgc2hhcGUgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG1heCA9IFRtYXgsIFRtaW4gPSBUbWluLCBDVG1pbiA9IENUbWluLCBDVG1heCA9IENUbWF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWhhdiA9ICdib3RoJywgaW4uc2hhZGUgPSBUUlVFLCBidXJyb3cgPSBGQUxTRSwgY2xpbWIgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmh5ZCA9IG1pbl9oeWQsIGh5ZC5kZWF0aCA9IGh5ZC5kZWF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlkLnJhdGUgPSBoeWRfcmF0ZSwgcGN0X3dldCA9IHBjdF93ZXRfaGlnaCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhdGVyID0gRkFMU0UsIHdhdGVyLmFjdCA9IFRSVUUpCgpzaGFkX3dhcm1fZHJ5X21vZCA8LSBzaW0uZWN0byhtaWNyb193YXJtX2RyeSwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gRkFMU0UsIGNsaW1iID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2hpZ2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IEZBTFNFLCB3YXRlci5hY3QgPSBUUlVFKQoKIyBXQVRFUi1QUk9PRiBNT0RFTAp0cmVlX2N1cnJfd2V0X21vZCA8LSBzaW0uZWN0byhtaWNyb19jdXJyX3dldCwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gRkFMU0UsIGNsaW1iID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmh5ZCA9IG1pbl9oeWQsIGh5ZC5kZWF0aCA9IGh5ZC5kZWF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlkLnJhdGUgPSBoeWRfcmF0ZSwgcGN0X3dldCA9IHBjdF93ZXRfbG93LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2F0ZXIgPSBUUlVFLCB3YXRlci5hY3QgPSBUUlVFKQoKdHJlZV9jdXJyX2RyeV9tb2QgPC0gc2ltLmVjdG8obWljcm9fY3Vycl9kcnksIFd3X2cgPSBXd19nLCBzaGFwZSA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbWF4ID0gVG1heCwgVG1pbiA9IFRtaW4sIENUbWluID0gQ1RtaW4sIENUbWF4ID0gQ1RtYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaGF2ID0gJ2JvdGgnLCBpbi5zaGFkZSA9IFRSVUUsIGJ1cnJvdyA9IEZBTFNFLCBjbGltYiA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2xvdywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhdGVyID0gVFJVRSwgd2F0ZXIuYWN0ID0gVFJVRSkKCnRyZWVfd2FybV93ZXRfbW9kIDwtIHNpbS5lY3RvKG1pY3JvX3dhcm1fd2V0LCBXd19nID0gV3dfZywgc2hhcGUgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG1heCA9IFRtYXgsIFRtaW4gPSBUbWluLCBDVG1pbiA9IENUbWluLCBDVG1heCA9IENUbWF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWhhdiA9ICdib3RoJywgaW4uc2hhZGUgPSBUUlVFLCBidXJyb3cgPSBGQUxTRSwgY2xpbWIgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uaHlkID0gbWluX2h5ZCwgaHlkLmRlYXRoID0gaHlkLmRlYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeWQucmF0ZSA9IGh5ZF9yYXRlLCBwY3Rfd2V0ID0gcGN0X3dldF9sb3csIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IFRSVUUsIHdhdGVyLmFjdCA9IFRSVUUpCgp0cmVlX3dhcm1fZHJ5X21vZCA8LSBzaW0uZWN0byhtaWNyb193YXJtX2RyeSwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gRkFMU0UsIGNsaW1iID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmh5ZCA9IG1pbl9oeWQsIGh5ZC5kZWF0aCA9IGh5ZC5kZWF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlkLnJhdGUgPSBoeWRfcmF0ZSwgcGN0X3dldCA9IHBjdF93ZXRfbG93LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2F0ZXIgPSBUUlVFLCB3YXRlci5hY3QgPSBUUlVFKQoKIyBCVVJST1dJTkcgTU9ERUwKYnVycl9jdXJyX3dldF9tb2QgPC0gc2ltLmVjdG8obWljcm9fY3Vycl93ZXQsIFd3X2cgPSBXd19nLCBzaGFwZSA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbWF4ID0gVG1heCwgVG1pbiA9IFRtaW4sIENUbWluID0gQ1RtaW4sIENUbWF4ID0gQ1RtYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaGF2ID0gJ2JvdGgnLCBpbi5zaGFkZSA9IFRSVUUsIGJ1cnJvdyA9IFRSVUUsIGNsaW1iID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2hpZ2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IFRSVUUsIHdhdGVyLmFjdCA9IFRSVUUpCgpidXJyX2N1cnJfZHJ5X21vZCA8LSBzaW0uZWN0byhtaWNyb19jdXJyX2RyeSwgV3dfZyA9IFd3X2csIHNoYXBlID0gNCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRtYXggPSBUbWF4LCBUbWluID0gVG1pbiwgQ1RtaW4gPSBDVG1pbiwgQ1RtYXggPSBDVG1heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVoYXYgPSAnYm90aCcsIGluLnNoYWRlID0gVFJVRSwgYnVycm93ID0gVFJVRSwgY2xpbWIgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLmh5ZCA9IG1pbl9oeWQsIGh5ZC5kZWF0aCA9IGh5ZC5kZWF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHlkLnJhdGUgPSBoeWRfcmF0ZSwgcGN0X3dldCA9IHBjdF93ZXRfaGlnaCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdhdGVyID0gVFJVRSwgd2F0ZXIuYWN0ID0gVFJVRSkKCmJ1cnJfd2FybV93ZXRfbW9kIDwtIHNpbS5lY3RvKG1pY3JvX3dhcm1fd2V0LCBXd19nID0gV3dfZywgc2hhcGUgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG1heCA9IFRtYXgsIFRtaW4gPSBUbWluLCBDVG1pbiA9IENUbWluLCBDVG1heCA9IENUbWF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWhhdiA9ICdib3RoJywgaW4uc2hhZGUgPSBUUlVFLCBidXJyb3cgPSBUUlVFLCBjbGltYiA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uaHlkID0gbWluX2h5ZCwgaHlkLmRlYXRoID0gaHlkLmRlYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoeWQucmF0ZSA9IGh5ZF9yYXRlLCBwY3Rfd2V0ID0gcGN0X3dldF9oaWdoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2F0ZXIgPSBUUlVFLCB3YXRlci5hY3QgPSBUUlVFKQoKYnVycl93YXJtX2RyeV9tb2QgPC0gc2ltLmVjdG8obWljcm9fd2FybV9kcnksIFd3X2cgPSBXd19nLCBzaGFwZSA9IDQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUbWF4ID0gVG1heCwgVG1pbiA9IFRtaW4sIENUbWluID0gQ1RtaW4sIENUbWF4ID0gQ1RtYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlaGF2ID0gJ2JvdGgnLCBpbi5zaGFkZSA9IFRSVUUsIGJ1cnJvdyA9IFRSVUUsIGNsaW1iID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5oeWQgPSBtaW5faHlkLCBoeWQuZGVhdGggPSBoeWQuZGVhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh5ZC5yYXRlID0gaHlkX3JhdGUsIHBjdF93ZXQgPSBwY3Rfd2V0X2hpZ2gsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXRlciA9IFRSVUUsIHdhdGVyLmFjdCA9IFRSVUUpCmBgYAoKCmBgYCB7ciBhY3RpdmV9CiMgU0hBREUgTU9ERUwKc2hhZF9jdXJyX3dldF9kZiA8LSBkYXRhLmZyYW1lKHNoYWRfY3Vycl93ZXRfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IHNoYWRfY3Vycl93ZXRfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoY3Vycl93ZXQgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgpzaGFkX2N1cnJfZHJ5X2RmIDwtIGRhdGEuZnJhbWUoc2hhZF9jdXJyX2RyeV9tb2QkYWN0KSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiaG91ciIpICU+JQogIGRwbHlyOjpyZW5hbWUoYWN0aXZlID0gc2hhZF9jdXJyX2RyeV9tb2QuYWN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGRheSA9IGNlaWxpbmcoMTo4NzYwLzI0KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGRheSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShjdXJyX2RyeSA9IGxlbmd0aChhY3RpdmVbYWN0aXZlID09IFRSVUVdKSkKCnNoYWRfd2FybV93ZXRfZGYgPC0gZGF0YS5mcmFtZShzaGFkX3dhcm1fd2V0X21vZCRhY3QpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJob3VyIikgJT4lCiAgZHBseXI6OnJlbmFtZShhY3RpdmUgPSBzaGFkX3dhcm1fd2V0X21vZC5hY3QpICU+JQogIGRwbHlyOjptdXRhdGUoZGF5ID0gY2VpbGluZygxOjg3NjAvMjQpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoZGF5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKHdhcm1fd2V0ID0gbGVuZ3RoKGFjdGl2ZVthY3RpdmUgPT0gVFJVRV0pKQoKc2hhZF93YXJtX2RyeV9kZiA8LSBkYXRhLmZyYW1lKHNoYWRfd2FybV9kcnlfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IHNoYWRfd2FybV9kcnlfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2Uod2FybV9kcnkgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgpzaGFkX21vZGVsIDwtIHNoYWRfY3Vycl93ZXRfZGYgJT4lCiAgbWVyZ2Uoc2hhZF9jdXJyX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2Uoc2hhZF93YXJtX3dldF9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2Uoc2hhZF93YXJtX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgcGl2b3RfbG9uZ2VyKCFkYXksIG5hbWVzX3RvID0gImNvbmRpdGlvbiIsIHZhbHVlc190byA9ICJob3VycyIpICU+JQogIGRwbHlyOjptdXRhdGUoY29uZGl0aW9uID0gZmFjdG9yKGNvbmRpdGlvbiwgbGV2ZWxzID0gYygid2FybV9kcnkiLCAid2FybV93ZXQiLCAiY3Vycl9kcnkiLCAiY3Vycl93ZXQiKSksCiAgICAgICAgICAgICAgICBzZWFzb24gPSBjYXNlX3doZW4oCiAgICBkYXkgPj0gMzM1IH4gInN1bW1lciIsCiAgICBkYXkgPj0gMSAmIGRheSA8PSA2MSB+ICJzdW1tZXIiLAogICAgZGF5ID49IDYyICYgZGF5IDw9IDE1MyB+ICJhdXR1bW4iLAogICAgZGF5ID49IDE1NCAmIGRheSA8PSAyNDQgfiAid2ludGVyIiwKICAgIGRheSA+PSAyNDUgJiBkYXkgPD0gMzM0IH4gInNwcmluZyIKICAgICkpCgojIFRSRUUgTU9ERUwKdHJlZV9jdXJyX3dldF9kZiA8LSBkYXRhLmZyYW1lKHRyZWVfY3Vycl93ZXRfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IHRyZWVfY3Vycl93ZXRfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoY3Vycl93ZXQgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgp0cmVlX2N1cnJfZHJ5X2RmIDwtIGRhdGEuZnJhbWUodHJlZV9jdXJyX2RyeV9tb2QkYWN0KSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiaG91ciIpICU+JQogIGRwbHlyOjpyZW5hbWUoYWN0aXZlID0gdHJlZV9jdXJyX2RyeV9tb2QuYWN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGRheSA9IGNlaWxpbmcoMTo4NzYwLzI0KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGRheSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShjdXJyX2RyeSA9IGxlbmd0aChhY3RpdmVbYWN0aXZlID09IFRSVUVdKSkKCnRyZWVfd2FybV93ZXRfZGYgPC0gZGF0YS5mcmFtZSh0cmVlX3dhcm1fd2V0X21vZCRhY3QpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJob3VyIikgJT4lCiAgZHBseXI6OnJlbmFtZShhY3RpdmUgPSB0cmVlX3dhcm1fd2V0X21vZC5hY3QpICU+JQogIGRwbHlyOjptdXRhdGUoZGF5ID0gY2VpbGluZygxOjg3NjAvMjQpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoZGF5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKHdhcm1fd2V0ID0gbGVuZ3RoKGFjdGl2ZVthY3RpdmUgPT0gVFJVRV0pKQoKdHJlZV93YXJtX2RyeV9kZiA8LSBkYXRhLmZyYW1lKHRyZWVfd2FybV9kcnlfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IHRyZWVfd2FybV9kcnlfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2Uod2FybV9kcnkgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgp0cmVlX21vZGVsIDwtIHRyZWVfY3Vycl93ZXRfZGYgJT4lCiAgbWVyZ2UodHJlZV9jdXJyX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2UodHJlZV93YXJtX3dldF9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2UodHJlZV93YXJtX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgcGl2b3RfbG9uZ2VyKCFkYXksIG5hbWVzX3RvID0gImNvbmRpdGlvbiIsIHZhbHVlc190byA9ICJob3VycyIpICU+JQogIGRwbHlyOjptdXRhdGUoY29uZGl0aW9uID0gZmFjdG9yKGNvbmRpdGlvbiwgbGV2ZWxzID0gYygid2FybV9kcnkiLCAid2FybV93ZXQiLCAiY3Vycl9kcnkiLCAiY3Vycl93ZXQiKSksCiAgICAgICAgICAgICAgICBzZWFzb24gPSBjYXNlX3doZW4oCiAgICBkYXkgPj0gMzM1IH4gInN1bW1lciIsCiAgICBkYXkgPj0gMSAmIGRheSA8PSA2MSB+ICJzdW1tZXIiLAogICAgZGF5ID49IDYyICYgZGF5IDw9IDE1MyB+ICJhdXR1bW4iLAogICAgZGF5ID49IDE1NCAmIGRheSA8PSAyNDQgfiAid2ludGVyIiwKICAgIGRheSA+PSAyNDUgJiBkYXkgPD0gMzM0IH4gInNwcmluZyIKICAgICkpCgojIEZPU1NPUklBTCBNT0RFTApidXJyX2N1cnJfd2V0X2RmIDwtIGRhdGEuZnJhbWUoYnVycl9jdXJyX3dldF9tb2QkYWN0KSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiaG91ciIpICU+JQogIGRwbHlyOjpyZW5hbWUoYWN0aXZlID0gYnVycl9jdXJyX3dldF9tb2QuYWN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGRheSA9IGNlaWxpbmcoMTo4NzYwLzI0KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGRheSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShjdXJyX3dldCA9IGxlbmd0aChhY3RpdmVbYWN0aXZlID09IFRSVUVdKSkKCmJ1cnJfY3Vycl9kcnlfZGYgPC0gZGF0YS5mcmFtZShidXJyX2N1cnJfZHJ5X21vZCRhY3QpICU+JQogIHRpYmJsZTo6cm93aWRfdG9fY29sdW1uKCJob3VyIikgJT4lCiAgZHBseXI6OnJlbmFtZShhY3RpdmUgPSBidXJyX2N1cnJfZHJ5X21vZC5hY3QpICU+JQogIGRwbHlyOjptdXRhdGUoZGF5ID0gY2VpbGluZygxOjg3NjAvMjQpKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoZGF5KSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGN1cnJfZHJ5ID0gbGVuZ3RoKGFjdGl2ZVthY3RpdmUgPT0gVFJVRV0pKQoKYnVycl93YXJtX3dldF9kZiA8LSBkYXRhLmZyYW1lKGJ1cnJfd2FybV93ZXRfbW9kJGFjdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImhvdXIiKSAlPiUKICBkcGx5cjo6cmVuYW1lKGFjdGl2ZSA9IGJ1cnJfd2FybV93ZXRfbW9kLmFjdCkgJT4lCiAgZHBseXI6Om11dGF0ZShkYXkgPSBjZWlsaW5nKDE6ODc2MC8yNCkpICU+JQogIGRwbHlyOjpncm91cF9ieShkYXkpICU+JQogIGRwbHlyOjpzdW1tYXJpc2Uod2FybV93ZXQgPSBsZW5ndGgoYWN0aXZlW2FjdGl2ZSA9PSBUUlVFXSkpCgpidXJyX3dhcm1fZHJ5X2RmIDwtIGRhdGEuZnJhbWUoYnVycl93YXJtX2RyeV9tb2QkYWN0KSAlPiUKICB0aWJibGU6OnJvd2lkX3RvX2NvbHVtbigiaG91ciIpICU+JQogIGRwbHlyOjpyZW5hbWUoYWN0aXZlID0gYnVycl93YXJtX2RyeV9tb2QuYWN0KSAlPiUKICBkcGx5cjo6bXV0YXRlKGRheSA9IGNlaWxpbmcoMTo4NzYwLzI0KSkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGRheSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZSh3YXJtX2RyeSA9IGxlbmd0aChhY3RpdmVbYWN0aXZlID09IFRSVUVdKSkKCmJ1cnJfbW9kZWwgPC0gYnVycl9jdXJyX3dldF9kZiAlPiUKICBtZXJnZShidXJyX2N1cnJfZHJ5X2RmLCBieSA9ICJkYXkiKSAlPiUKICBtZXJnZShidXJyX3dhcm1fd2V0X2RmLCBieSA9ICJkYXkiKSAlPiUKICBtZXJnZShidXJyX3dhcm1fZHJ5X2RmLCBieSA9ICJkYXkiKSAlPiUKICBwaXZvdF9sb25nZXIoIWRheSwgbmFtZXNfdG8gPSAiY29uZGl0aW9uIiwgdmFsdWVzX3RvID0gImhvdXJzIikgJT4lCiAgZHBseXI6Om11dGF0ZShjb25kaXRpb24gPSBmYWN0b3IoY29uZGl0aW9uLCBsZXZlbHMgPSBjKCJ3YXJtX2RyeSIsICJ3YXJtX3dldCIsICJjdXJyX2RyeSIsICJjdXJyX3dldCIpKSwKICAgICAgICAgICAgICAgIHNlYXNvbiA9IGNhc2Vfd2hlbigKICAgIGRheSA+PSAzMzUgfiAic3VtbWVyIiwKICAgIGRheSA+PSAxICYgZGF5IDw9IDYxIH4gInN1bW1lciIsCiAgICBkYXkgPj0gNjIgJiBkYXkgPD0gMTUzIH4gImF1dHVtbiIsCiAgICBkYXkgPj0gMTU0ICYgZGF5IDw9IDI0NCB+ICJ3aW50ZXIiLAogICAgZGF5ID49IDI0NSAmIGRheSA8PSAzMzQgfiAic3ByaW5nIgogICAgKSkKYGBgCgojIyBNb2RlbCBvdXRwdXQgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0KCiMjIyBUYWJsZSBTNmEgLSBTdW1tYXJ5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTNmEuKiogVG90YWwgcG90ZW50aWFsIGFjdGl2aXR5IGhvdXJzIHBlciB5ZWFyICgkdF97YWN0fSQpIGZvciBhIGByIFd3X2dgIGcgZnJvZyB1bmRlciBkaWZmZXJlbnQgd2FybWluZyAoY3VycmVudCBvciB3YXJtaW5nKSBhbmQgZHJvdWdodCAobm9ybWFsIG9yIGRyb3VnaHQpIGNvbmRpdGlvbnMgd2l0aCBkaWZmZXJlbnQgd2F0ZXItc2F2aW5nIHN0cmF0ZWdpZXMuCgpgYGAge3IgdGFibGUgczZhfQpkYXRhLmZyYW1lKHN0cmF0ZWd5ID0gYygiU2hhZGUgb25seSIsICJTaGFkZSBvbmx5IiwgIlNoYWRlIG9ubHkiLCAiU2hhZGUgb25seSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJXYXRlcnByb29mIiwgIldhdGVycHJvb2YiLCAiV2F0ZXJwcm9vZiIsICJXYXRlcnByb29mIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkJ1cnJvd2luZyIsICJCdXJyb3dpbmciLCAiQnVycm93aW5nIiwgIkJ1cnJvd2luZyIpLAogICAgICAgICAgIHRlbXAgPSBjKCJjdXJyZW50IiwgImN1cnJlbnQiLCAid2FybWluZyIsICJ3YXJtaW5nIiksCiAgICAgICAgICAgcmFpbiA9IGMoIm5vcm1hbCIsICJkcm91Z2h0IiksCiAgICAgICAgICAgdF9hY3RfaCA9IGMoc3VtKHNoYWRfY3Vycl93ZXRfZGYkY3Vycl93ZXQpLCBzdW0oc2hhZF9jdXJyX2RyeV9kZiRjdXJyX2RyeSksIHN1bShzaGFkX3dhcm1fd2V0X2RmJHdhcm1fd2V0KSwgc3VtKHNoYWRfd2FybV9kcnlfZGYkd2FybV9kcnkpLAogICAgICAgICAgICAgICAgICAgICAgIHN1bSh0cmVlX2N1cnJfd2V0X2RmJGN1cnJfd2V0KSwgc3VtKHRyZWVfY3Vycl9kcnlfZGYkY3Vycl9kcnkpLCBzdW0odHJlZV93YXJtX3dldF9kZiR3YXJtX3dldCksIHN1bSh0cmVlX3dhcm1fZHJ5X2RmJHdhcm1fZHJ5KSwKICAgICAgICAgICAgICAgICAgICAgICBzdW0oYnVycl9jdXJyX3dldF9kZiRjdXJyX3dldCksIHN1bShidXJyX2N1cnJfZHJ5X2RmJGN1cnJfZHJ5KSwgc3VtKGJ1cnJfd2FybV93ZXRfZGYkd2FybV93ZXQpLCBzdW0oYnVycl93YXJtX2RyeV9kZiR3YXJtX2RyeSkpLAogICAgICAgICAgIHRfYWN0X3BlciA9IGMoc3VtKHNoYWRfY3Vycl93ZXRfZGYkY3Vycl93ZXQpIC8gODc2MCAqIDEwMCwgc3VtKHNoYWRfY3Vycl9kcnlfZGYkY3Vycl9kcnkpIC8gODc2MCAqIDEwMCwgc3VtKHNoYWRfd2FybV93ZXRfZGYkd2FybV93ZXQpIC8gODc2MCAqIDEwMCwgc3VtKHNoYWRfd2FybV9kcnlfZGYkd2FybV9kcnkpIC8gODc2MCAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgICBzdW0odHJlZV9jdXJyX3dldF9kZiRjdXJyX3dldCkgLyA4NzYwICogMTAwLCBzdW0odHJlZV9jdXJyX2RyeV9kZiRjdXJyX2RyeSkgLyA4NzYwICogMTAwLCBzdW0odHJlZV93YXJtX3dldF9kZiR3YXJtX3dldCkgLyA4NzYwICogMTAwLCBzdW0odHJlZV93YXJtX2RyeV9kZiR3YXJtX2RyeSkgLyA4NzYwICogMTAwLAogICAgICAgICAgICAgICAgICAgICAgIHN1bShidXJyX2N1cnJfd2V0X2RmJGN1cnJfd2V0KSAvIDg3NjAgKiAxMDAsIHN1bShidXJyX2N1cnJfZHJ5X2RmJGN1cnJfZHJ5KSAvIDg3NjAgKiAxMDAsIHN1bShidXJyX3dhcm1fd2V0X2RmJHdhcm1fd2V0KSAvIDg3NjAgKiAxMDAsIHN1bShidXJyX3dhcm1fZHJ5X2RmJHdhcm1fZHJ5KSAvIDg3NjAgKiAxMDApKSAlPiUKICBrbml0cjo6a2FibGUoY29sLm5hbWVzID0gYygiV2F0ZXItc2F2aW5nIHN0cmF0ZWd5IiwgIldhcm1pbmcgc2ltdWxhdGlvbiIsICJEcm91Z2h0IHNpbXVsYXRpb24iLCAiJHRfe2FjdH0kIChoKSIsICIkdF97YWN0fSQgKCUpIikpCmBgYAoKKioqCgojIyMgVGFibGUgUzZiIC0gUmVsYXRpdmUgY2hhbmdlIHllYXIgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgoqKlRhYmxlIFM2Yi4qKiBDaGFuZ2UgaW4gJHRfe2FjdH0kICglKSBmb3IgZWFjaCB3YXRlci1zYXZpbmcgc3RyYXRlZ3kgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgbm9ybWFsIHNjZW5hcmlvIHVuZGVyIHdhcm1pbmcgb25seSwgZHJvdWdodCBvbmx5LCBhbmQgd2FybWluZyBhbmQgZHJvdWdodCBjb21iaW5lZC4gCgpgYGAge3IgdGFibGUgczZifQpkYXRhLmZyYW1lKHN0cmF0ZWd5ID0gYygiU2hhZGUgb25seSIsIldhdGVycHJvb2YiLCAiQnVycm93aW5nIiksCiAgICAgICAgICAgY3Vycl93ZXQgPSBjKHN1bShzaGFkX2N1cnJfd2V0X2RmJGN1cnJfd2V0KSwgc3VtKHRyZWVfY3Vycl93ZXRfZGYkY3Vycl93ZXQpLCBzdW0oYnVycl9jdXJyX3dldF9kZiRjdXJyX3dldCkpLAogICAgICAgICAgIGN1cnJfZHJ5ID0gYyhzdW0oc2hhZF9jdXJyX2RyeV9kZiRjdXJyX2RyeSksIHN1bSh0cmVlX2N1cnJfZHJ5X2RmJGN1cnJfZHJ5KSwgc3VtKGJ1cnJfY3Vycl9kcnlfZGYkY3Vycl9kcnkpKSwKICAgICAgICAgICB3YXJtX3dldCA9IGMoc3VtKHNoYWRfd2FybV93ZXRfZGYkd2FybV93ZXQpLCBzdW0odHJlZV93YXJtX3dldF9kZiR3YXJtX3dldCksIHN1bShidXJyX3dhcm1fd2V0X2RmJHdhcm1fd2V0KSksCiAgICAgICAgICAgd2FybV9kcnkgPSBjKHN1bShzaGFkX3dhcm1fZHJ5X2RmJHdhcm1fZHJ5KSwgc3VtKHRyZWVfd2FybV9kcnlfZGYkd2FybV9kcnkpLCBzdW0oYnVycl93YXJtX2RyeV9kZiR3YXJtX2RyeSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRlbHRhX3dhcm0gICAgID0gKHdhcm1fd2V0IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDAsCiAgICAgICAgICAgICAgICBkZWx0YV9kcnkgICAgICA9IChjdXJyX2RyeSAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwLAogICAgICAgICAgICAgICAgZGVsdGFfd2FybV9kcnkgPSAod2FybV9kcnkgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCkgJT4lCiAgZHBseXI6OnNlbGVjdCgtYyhjdXJyX3dldDp3YXJtX2RyeSkpICU+JQogIGtuaXRyOjprYWJsZShjb2wubmFtZXMgPSBjKCJXYXRlci1zYXZpbmcgc3RyYXRlZ3kiLCAiJFxcRGVsdGEkIHdhcm1pbmcgb25seSAoJSkiLCAiJFxcRGVsdGEkIGRyb3VnaHQgb25seSAoJSkiLCAiJFxcRGVsdGEkIHdhcm1pbmcgYW5kIGRyb3VnaHQgKCUpIikpCmBgYAoKKioqCgojIyMgVGFibGUgUzZjIC0gUmVsYXRpdmUgY2hhbmdlIHNlYXNvbiB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzZjLioqIENoYW5nZSBpbiAkdF97YWN0fSQgKCUpIGZvciBlYWNoIHdhdGVyLXNhdmluZyBzdHJhdGVneSByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBub3JtYWwgc2NlbmFyaW8gdW5kZXIgd2FybWluZyBvbmx5LCBkcm91Z2h0IG9ubHksIGFuZCB3YXJtaW5nIGFuZCBkcm91Z2h0IGNvbWJpbmVkLiAKCmBgYCB7ciB0YWJsZSBzNmN9CiMgc3VtbWVyCnNoYWRfbW9kZWxfc3VtbWVyIDwtIHNoYWRfbW9kZWwgJT4lCiAgZHBseXI6OmZpbHRlcihzZWFzb24gPT0gInN1bW1lciIpICU+JQogIGRwbHlyOjpncm91cF9ieShjb25kaXRpb24pICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaG91cnMgPSBzdW0oaG91cnMpKQoKdHJlZV9tb2RlbF9zdW1tZXIgPC0gdHJlZV9tb2RlbCAlPiUKICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiA9PSAic3VtbWVyIikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGNvbmRpdGlvbikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShob3VycyA9IHN1bShob3VycykpCgpidXJyX21vZGVsX3N1bW1lciA8LSBidXJyX21vZGVsICU+JQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uID09ICJzdW1tZXIiKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGhvdXJzID0gc3VtKGhvdXJzKSkKCnRhYl9zdW1tZXIgPC0gZGF0YS5mcmFtZShzdHJhdGVneSA9IGMoIlNoYWRlIG9ubHkiLCJXYXRlcnByb29mIiwgIkJ1cnJvd2luZyIpLAogICAgICAgICAgIGN1cnJfd2V0ID0gYyhzaGFkX21vZGVsX3N1bW1lciRob3Vyc1s0XSwgdHJlZV9tb2RlbF9zdW1tZXIkaG91cnNbNF0sIGJ1cnJfbW9kZWxfc3VtbWVyJGhvdXJzWzRdKSwKICAgICAgICAgICBjdXJyX2RyeSA9IGMoc2hhZF9tb2RlbF9zdW1tZXIkaG91cnNbM10sIHRyZWVfbW9kZWxfc3VtbWVyJGhvdXJzWzNdLCBidXJyX21vZGVsX3N1bW1lciRob3Vyc1szXSksCiAgICAgICAgICAgd2FybV93ZXQgPSBjKHNoYWRfbW9kZWxfc3VtbWVyJGhvdXJzWzJdLCB0cmVlX21vZGVsX3N1bW1lciRob3Vyc1syXSwgYnVycl9tb2RlbF9zdW1tZXIkaG91cnNbMl0pLAogICAgICAgICAgIHdhcm1fZHJ5ID0gYyhzaGFkX21vZGVsX3N1bW1lciRob3Vyc1sxXSwgdHJlZV9tb2RlbF9zdW1tZXIkaG91cnNbMV0sIGJ1cnJfbW9kZWxfc3VtbWVyJGhvdXJzWzFdKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkZWx0YV93YXJtICAgICA9ICh3YXJtX3dldCAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwLAogICAgICAgICAgICAgICAgZGVsdGFfZHJ5ICAgICAgPSAoY3Vycl9kcnkgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCwKICAgICAgICAgICAgICAgIGRlbHRhX3dhcm1fZHJ5ID0gKHdhcm1fZHJ5IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDApICU+JQogIGRwbHlyOjpzZWxlY3QoLWMoY3Vycl93ZXQ6d2FybV9kcnkpKSAlPiUKICB0aWJibGU6OmFkZF9yb3coc3RyYXRlZ3kgPSAiKipTdW1tZXIqKiIsIC5iZWZvcmUgPSAxKQoKIyBhdXR1bW4Kc2hhZF9tb2RlbF9hdXR1bW4gPC0gc2hhZF9tb2RlbCAlPiUKICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiA9PSAiYXV0dW1uIikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGNvbmRpdGlvbikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShob3VycyA9IHN1bShob3VycykpCgp0cmVlX21vZGVsX2F1dHVtbiA8LSB0cmVlX21vZGVsICU+JQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uID09ICJhdXR1bW4iKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGhvdXJzID0gc3VtKGhvdXJzKSkKCmJ1cnJfbW9kZWxfYXV0dW1uIDwtIGJ1cnJfbW9kZWwgJT4lCiAgZHBseXI6OmZpbHRlcihzZWFzb24gPT0gImF1dHVtbiIpICU+JQogIGRwbHlyOjpncm91cF9ieShjb25kaXRpb24pICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaG91cnMgPSBzdW0oaG91cnMpKQoKdGFiX2F1dHVtbiA8LSBkYXRhLmZyYW1lKHN0cmF0ZWd5ID0gYygiU2hhZGUgb25seSIsIldhdGVycHJvb2YiLCAiQnVycm93aW5nIiksCiAgICAgICAgICAgY3Vycl93ZXQgPSBjKHNoYWRfbW9kZWxfYXV0dW1uJGhvdXJzWzRdLCB0cmVlX21vZGVsX2F1dHVtbiRob3Vyc1s0XSwgYnVycl9tb2RlbF9hdXR1bW4kaG91cnNbNF0pLAogICAgICAgICAgIGN1cnJfZHJ5ID0gYyhzaGFkX21vZGVsX2F1dHVtbiRob3Vyc1szXSwgdHJlZV9tb2RlbF9hdXR1bW4kaG91cnNbM10sIGJ1cnJfbW9kZWxfYXV0dW1uJGhvdXJzWzNdKSwKICAgICAgICAgICB3YXJtX3dldCA9IGMoc2hhZF9tb2RlbF9hdXR1bW4kaG91cnNbMl0sIHRyZWVfbW9kZWxfYXV0dW1uJGhvdXJzWzJdLCBidXJyX21vZGVsX2F1dHVtbiRob3Vyc1syXSksCiAgICAgICAgICAgd2FybV9kcnkgPSBjKHNoYWRfbW9kZWxfYXV0dW1uJGhvdXJzWzFdLCB0cmVlX21vZGVsX2F1dHVtbiRob3Vyc1sxXSwgYnVycl9tb2RlbF9hdXR1bW4kaG91cnNbMV0pKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRlbHRhX3dhcm0gICAgID0gKHdhcm1fd2V0IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDAsCiAgICAgICAgICAgICAgICBkZWx0YV9kcnkgICAgICA9IChjdXJyX2RyeSAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwLAogICAgICAgICAgICAgICAgZGVsdGFfd2FybV9kcnkgPSAod2FybV9kcnkgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCkgJT4lCiAgZHBseXI6OnNlbGVjdCgtYyhjdXJyX3dldDp3YXJtX2RyeSkpICU+JQogIHRpYmJsZTo6YWRkX3JvdyhzdHJhdGVneSA9ICIqKkF1dHVtbioqIiwgLmJlZm9yZSA9IDEpCgojIHdpbnRlcgpzaGFkX21vZGVsX3dpbnRlciA8LSBzaGFkX21vZGVsICU+JQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uID09ICJ3aW50ZXIiKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGhvdXJzID0gc3VtKGhvdXJzKSkKCnRyZWVfbW9kZWxfd2ludGVyIDwtIHRyZWVfbW9kZWwgJT4lCiAgZHBseXI6OmZpbHRlcihzZWFzb24gPT0gIndpbnRlciIpICU+JQogIGRwbHlyOjpncm91cF9ieShjb25kaXRpb24pICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaG91cnMgPSBzdW0oaG91cnMpKQoKYnVycl9tb2RlbF93aW50ZXIgPC0gYnVycl9tb2RlbCAlPiUKICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiA9PSAid2ludGVyIikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGNvbmRpdGlvbikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShob3VycyA9IHN1bShob3VycykpCgp0YWJfd2ludGVyIDwtIGRhdGEuZnJhbWUoc3RyYXRlZ3kgPSBjKCJTaGFkZSBvbmx5IiwiV2F0ZXJwcm9vZiIsICJCdXJyb3dpbmciKSwKICAgICAgICAgICBjdXJyX3dldCA9IGMoc2hhZF9tb2RlbF93aW50ZXIkaG91cnNbNF0sIHRyZWVfbW9kZWxfd2ludGVyJGhvdXJzWzRdLCBidXJyX21vZGVsX3dpbnRlciRob3Vyc1s0XSksCiAgICAgICAgICAgY3Vycl9kcnkgPSBjKHNoYWRfbW9kZWxfd2ludGVyJGhvdXJzWzNdLCB0cmVlX21vZGVsX3dpbnRlciRob3Vyc1szXSwgYnVycl9tb2RlbF93aW50ZXIkaG91cnNbM10pLAogICAgICAgICAgIHdhcm1fd2V0ID0gYyhzaGFkX21vZGVsX3dpbnRlciRob3Vyc1syXSwgdHJlZV9tb2RlbF93aW50ZXIkaG91cnNbMl0sIGJ1cnJfbW9kZWxfd2ludGVyJGhvdXJzWzJdKSwKICAgICAgICAgICB3YXJtX2RyeSA9IGMoc2hhZF9tb2RlbF93aW50ZXIkaG91cnNbMV0sIHRyZWVfbW9kZWxfd2ludGVyJGhvdXJzWzFdLCBidXJyX21vZGVsX3dpbnRlciRob3Vyc1sxXSkpICU+JQogIGRwbHlyOjptdXRhdGUoZGVsdGFfd2FybSAgICAgPSAod2FybV93ZXQgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCwKICAgICAgICAgICAgICAgIGRlbHRhX2RyeSAgICAgID0gKGN1cnJfZHJ5IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDAsCiAgICAgICAgICAgICAgICBkZWx0YV93YXJtX2RyeSA9ICh3YXJtX2RyeSAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwKSAlPiUKICBkcGx5cjo6c2VsZWN0KC1jKGN1cnJfd2V0Ondhcm1fZHJ5KSkgJT4lCiAgdGliYmxlOjphZGRfcm93KHN0cmF0ZWd5ID0gIioqV2ludGVyKioiLCAuYmVmb3JlID0gMSkKCiMgc3ByaW5nCnNoYWRfbW9kZWxfc3ByaW5nIDwtIHNoYWRfbW9kZWwgJT4lCiAgZHBseXI6OmZpbHRlcihzZWFzb24gPT0gInNwcmluZyIpICU+JQogIGRwbHlyOjpncm91cF9ieShjb25kaXRpb24pICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaG91cnMgPSBzdW0oaG91cnMpKQoKdHJlZV9tb2RlbF9zcHJpbmcgPC0gdHJlZV9tb2RlbCAlPiUKICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiA9PSAic3ByaW5nIikgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGNvbmRpdGlvbikgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShob3VycyA9IHN1bShob3VycykpCgpidXJyX21vZGVsX3NwcmluZyA8LSBidXJyX21vZGVsICU+JQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uID09ICJzcHJpbmciKSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY29uZGl0aW9uKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGhvdXJzID0gc3VtKGhvdXJzKSkKCnRhYl9zcHJpbmcgPC0gZGF0YS5mcmFtZShzdHJhdGVneSA9IGMoIlNoYWRlIG9ubHkiLCJXYXRlcnByb29mIiwgIkJ1cnJvd2luZyIpLAogICAgICAgICAgIGN1cnJfd2V0ID0gYyhzaGFkX21vZGVsX3NwcmluZyRob3Vyc1s0XSwgdHJlZV9tb2RlbF9zcHJpbmckaG91cnNbNF0sIGJ1cnJfbW9kZWxfc3ByaW5nJGhvdXJzWzRdKSwKICAgICAgICAgICBjdXJyX2RyeSA9IGMoc2hhZF9tb2RlbF9zcHJpbmckaG91cnNbM10sIHRyZWVfbW9kZWxfc3ByaW5nJGhvdXJzWzNdLCBidXJyX21vZGVsX3NwcmluZyRob3Vyc1szXSksCiAgICAgICAgICAgd2FybV93ZXQgPSBjKHNoYWRfbW9kZWxfc3ByaW5nJGhvdXJzWzJdLCB0cmVlX21vZGVsX3NwcmluZyRob3Vyc1syXSwgYnVycl9tb2RlbF9zcHJpbmckaG91cnNbMl0pLAogICAgICAgICAgIHdhcm1fZHJ5ID0gYyhzaGFkX21vZGVsX3NwcmluZyRob3Vyc1sxXSwgdHJlZV9tb2RlbF9zcHJpbmckaG91cnNbMV0sIGJ1cnJfbW9kZWxfc3ByaW5nJGhvdXJzWzFdKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkZWx0YV93YXJtICAgICA9ICh3YXJtX3dldCAtIGN1cnJfd2V0KSAvIGN1cnJfd2V0ICogMTAwLAogICAgICAgICAgICAgICAgZGVsdGFfZHJ5ICAgICAgPSAoY3Vycl9kcnkgLSBjdXJyX3dldCkgLyBjdXJyX3dldCAqIDEwMCwKICAgICAgICAgICAgICAgIGRlbHRhX3dhcm1fZHJ5ID0gKHdhcm1fZHJ5IC0gY3Vycl93ZXQpIC8gY3Vycl93ZXQgKiAxMDApICU+JQogIGRwbHlyOjpzZWxlY3QoLWMoY3Vycl93ZXQ6d2FybV9kcnkpKSAlPiUKICB0aWJibGU6OmFkZF9yb3coc3RyYXRlZ3kgPSAiKipTcHJpbmcqKiIsIC5iZWZvcmUgPSAxKQoKIyBSZW5kZXIgdGFibGUKYmluZF9yb3dzKHRhYl9zdW1tZXIsIHRhYl9hdXR1bW4sIHRhYl93aW50ZXIsIHRhYl9zcHJpbmcpICU+JSAKICByZW1vdmVfcm93bmFtZXMoKSAlPiUgCiAga25pdHI6OmthYmxlKGNvbC5uYW1lcyA9IGMoIldhdGVyLXNhdmluZyBzdHJhdGVneSIsICIkXFxEZWx0YSQgd2FybWluZyBvbmx5ICglKSIsICIkXFxEZWx0YSQgZHJvdWdodCBvbmx5ICglKSIsICIkXFxEZWx0YSQgd2FybWluZyBhbmQgZHJvdWdodCAoJSkiKSkKYGBgCgoqKioKCiMgRmlndXJlcyB7LX0KCkNvZGUgdG8gcHJvZHVjZSB0aGUgbWFpbiBkb2N1bWVudCBmaWd1cmVzIGFyZSBkZXRhaWxlZCBiZWxvdy4gRmlndXJlcyBwcm9kdWNlZCB3ZXJlIGZ1cnRoZXIgbW9kaWZpZWQgaW4gW0Fkb2JlIElsbHVzdHJhdG9yXShodHRwczovL3d3dy5hZG9iZS5jb20vYXUvcHJvZHVjdHMvaWxsdXN0cmF0b3IuaHRtbCkgZm9yIHB1YmxpY2F0aW9uLgoKIyMgRmlndXJlIDEgLSBBSSByaXNrIHstfQoKQ3JlYXRlIHBsb3RzIGZvciBtYWluIHRleHQgZmlndXJlIDEuCgpgYGB7ciBGaWcgMSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD05LCBmaWcuc2hvdz0naGlkZSd9CiMgUmVwcm9qZWN0IG1hcHMKcm9iX3Byb2ogICA8LSAiK3Byb2o9cm9iaW4gK2xvbl8wPTAgK3hfMD0wICt5XzA9MCArZWxscHM9V0dTODQgK2RhdHVtPVdHUzg0ICt1bml0cz1tICtub19kZWZzIiAKd29ybGRfcm9iICA8LSBzcFRyYW5zZm9ybSh3b3JsZF9zcGRmLCBDUlNvYmogPSByb2JfcHJvaikKCiMgbGFuZApkYXRhKCJsYW5kIiwgcGFja2FnZSA9ICJ0bWFwIikKbGFuZF9yYXN0ZXIgPC0gYXMobGFuZCwgIlJhc3RlciIpICMgY29udmVydCBmcm9tIHN0YXIgdG8gcmFzdGVyCmxhbmRfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMobGFuZF9yYXN0ZXIpKQoKZWxldmF0aW9uX3Jhc3RlciA8LSBwcm9qZWN0UmFzdGVyKGxhbmRfcmFzdGVyJGVsZXZhdGlvbiwgY3JzID0gcm9iX3Byb2opCnNsb3BlX3Jhc3RlciAgICAgPC0gcmFzdGVyOjp0ZXJyYWluKGVsZXZhdGlvbl9yYXN0ZXIsIG9wdCA9ICdzbG9wZScpCmFzcGVjdF9yYXN0ZXIgICAgPC0gcmFzdGVyOjp0ZXJyYWluKGVsZXZhdGlvbl9yYXN0ZXIsIG9wdCA9ICdhc3BlY3QnKQpoaWxsX3Jhc3RlciAgICAgIDwtIGhpbGxTaGFkZShzbG9wZV9yYXN0ZXIsIGFzcGVjdF9yYXN0ZXIsIDQwLCAyNzApICNzZXR0aW5nIHRoZSBlbGV2YXRpb24gYW5nbGUgKG9mIHRoZSBzdW4pIHRvIDQwIGFuZCB0aGUgZGlyZWN0aW9uIGFuZ2xlIG9mIHRoZSBsaWdodCB0byAyNzAKaGlsbF9tICAgICAgICAgICA8LSByYXN0ZXJUb1BvaW50cyhoaWxsX3Jhc3RlcikKaGlsbF9kZiAgICAgICAgICA8LSAgZGF0YS5mcmFtZShoaWxsX20pCmNvbG5hbWVzKGhpbGxfZGYpIDwtIGMoImxvbiIsICJsYXQiLCAiaGlsbCIpCgojIEZpZyAxYSAtIEFJIGN1cnJlbnQKQUlfcm9iICAgIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihhaV9yYXN0LCBjcnMgPSByb2JfcHJvaikKQUlfZGZfcm9iIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKEFJX3JvYikpIApBSV9kZl9yb2IgPC0gQUlfZGZfcm9iICU+JSAKICAjIFJlY29kZQogIGRwbHlyOjptdXRhdGUoY2F0ZWdvcnkgPSBjYXNlX3doZW4oCiAgICBpcy5pbmZpbml0ZShsYXllcikgfiAnSHVtaWQnLAogICAgbGF5ZXIgPj0gMC42NSB+ICdIdW1pZCcsICAgICAgICAgICAgICAgICAgICAgICAKICAgIGxheWVyID49IDAuNSAmIGxheWVyIDwgMC42NSB+ICdEcnkgc3ViLWh1bWlkJywgCiAgICBsYXllciA+PSAwLjIgJiBsYXllciA8IDAuNSB+ICdTZW1pLWFyaWQnLCAgICAgIAogICAgbGF5ZXIgPj0gMC4wNSAmIGxheWVyIDwgMC4yIH4gJ0FyaWQnLCAgICAgICAgIAogICAgbGF5ZXIgPCAwLjA1IH4gJ0h5cGVyLWFyaWQnICAgICAgICAgICAgICAgICAgICAKICApKSAlPiUgCiAgIyBDb252ZXJ0IHRvIG9yZGVyZWQgZmFjdG9yCiAgZHBseXI6Om11dGF0ZShjYXRlZ29yeSA9IGZhY3RvcihjYXRlZ29yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJ0h5cGVyLWFyaWQnLCAnQXJpZCcsICdTZW1pLWFyaWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKQUlfMkNfcm9iICAgIDwtIHByb2plY3RSYXN0ZXIoYWlfMkNfcmFzdCwgY3JzID0gcm9iX3Byb2opCkFJXzJDX2RmX3JvYiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhBSV8yQ19yb2IpKSAKQUlfMkNfZGZfcm9iIDwtIEFJXzJDX2RmX3JvYiAlPiUgCiAgIyBSZWNvZGUKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gY2FzZV93aGVuKAogICAgaXMuaW5maW5pdGUobGF5ZXIpIH4gJ0h1bWlkJywKICAgIGxheWVyID49IDAuNjUgfiAnSHVtaWQnLCAgICAgICAgICAgICAgICAgICAgICAgCiAgICBsYXllciA+PSAwLjUgJiBsYXllciA8IDAuNjUgfiAnRHJ5IHN1Yi1odW1pZCcsIAogICAgbGF5ZXIgPj0gMC4yICYgbGF5ZXIgPCAwLjUgfiAnU2VtaS1hcmlkJywgICAgIAogICAgbGF5ZXIgPj0gMC4wNSAmIGxheWVyIDwgMC4yIH4gJ0FyaWQnLCAgICAgICAgIAogICAgbGF5ZXIgPCAwLjA1IH4gJ0h5cGVyLWFyaWQnICAgICAgICAgICAgICAgIAogICkpICU+JSAKICAjIENvbnZlcnQgdG8gb3JkZXJlZCBmYWN0b3IKICBkcGx5cjo6bXV0YXRlKGNhdGVnb3J5ID0gZmFjdG9yKGNhdGVnb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnSHlwZXItYXJpZCcsICdBcmlkJywgJ1NlbWktYXJpZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdEcnkgc3ViLWh1bWlkJywgJ0h1bWlkJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpCgpBSV80Q19yb2IgICAgPC0gcHJvamVjdFJhc3RlcihhaV80Q19yYXN0LCBjcnMgPSByb2JfcHJvaikKQUlfNENfZGZfcm9iIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKEFJXzRDX3JvYikpIApBSV80Q19kZl9yb2IgPC0gQUlfNENfZGZfcm9iICU+JSAKICAjIFJlY29kZQogIGRwbHlyOjptdXRhdGUoY2F0ZWdvcnkgPSBjYXNlX3doZW4oCiAgICBpcy5pbmZpbml0ZShsYXllcikgfiAnSHVtaWQnLAogICAgbGF5ZXIgPj0gMC42NSB+ICdIdW1pZCcsICAgICAgICAgICAgICAgICAgICAgICAKICAgIGxheWVyID49IDAuNSAmIGxheWVyIDwgMC42NSB+ICdEcnkgc3ViLWh1bWlkJywgCiAgICBsYXllciA+PSAwLjIgJiBsYXllciA8IDAuNSB+ICdTZW1pLWFyaWQnLCAgICAgIAogICAgbGF5ZXIgPj0gMC4wNSAmIGxheWVyIDwgMC4yIH4gJ0FyaWQnLCAgICAgICAgIAogICAgbGF5ZXIgPCAwLjA1IH4gJ0h5cGVyLWFyaWQnICAgICAgICAgICAgICAgICAgICAKICApKSAlPiUgCiAgIyBDb252ZXJ0IHRvIG9yZGVyZWQgZmFjdG9yCiAgZHBseXI6Om11dGF0ZShjYXRlZ29yeSA9IGZhY3RvcihjYXRlZ29yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJ0h5cGVyLWFyaWQnLCAnQXJpZCcsICdTZW1pLWFyaWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRHJ5IHN1Yi1odW1pZCcsICdIdW1pZCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKYXJpZF9jb2wgPC0gYygnIzhFMDYzQicsICcjQ0I2RDUzJywgJyNFOTlBMkMnLCAnI0Y1RDU3OScsICd3aGl0ZScpCmFyaWRpdHlfcGxvdCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IEFJX2RmX3JvYiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGNhdGVnb3J5KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGFyaWRfY29sLAogICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKCJBcmlkaXR5IEluZGV4ICgxOTgxLTIwMTApIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAgCgojIEZpZyAxYiAtIFNwZWNpZXMgcmljaG5lc3MKYW51cmFuX3JvYiAgICA8LSBwcm9qZWN0UmFzdGVyKGFudXJhbl9zciwgY3JzID0gcm9iX3Byb2opCmFudXJhbl9kZl9yb2IgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoYW51cmFuX3JvYikpICU+JSBkcGx5cjo6cmVuYW1lKHNwZWNpZXNfbiA9IGxheWVyKQoKc3BfYnJlYWtzID0gYygxLCA1LCAyNSwgMTAwKQphbnVyYW5fcGxvdCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGFudXJhbl9kZl9yb2IsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBzcGVjaWVzX24pKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgY29sb3JzcGFjZTo6c2NhbGVfZmlsbF9jb250aW51b3VzX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJCbHVHcm4iLCB0cmFucyA9ICJsb2ciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNwX2JyZWFrcywgbGFiZWxzID0gc3BfYnJlYWtzKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoIkFudXJhbiBzcGVjaWVzIHJpY2huZXNzIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQoKQoKQUlfbWVyZ2VkIDwtIG1lcmdlKEFJX2RmX3JvYiwgQUlfMkNfZGZfcm9iLCBieSA9IGMoIngiLCAieSIpLCBhbGwueCA9IFQpICU+JQogIG1lcmdlKEFJXzRDX2RmX3JvYiwgYnkgPSBjKCJ4IiwgInkiKSwgYWxsLnggPSBUKSAlPiUKICBkcGx5cjo6cmVuYW1lKGxheWVyX2N1cnJlbnQgPSBsYXllci54LAogICAgICAgICAgICAgICAgY2F0ZWdvcnlfY3VycmVudCA9IGNhdGVnb3J5LngsCiAgICAgICAgICAgICAgICBsYXllcl8yQyAgPSBsYXllci55LAogICAgICAgICAgICAgICAgY2F0ZWdvcnlfMkMgPSBjYXRlZ29yeS55LAogICAgICAgICAgICAgICAgbGF5ZXJfNEMgID0gbGF5ZXIsCiAgICAgICAgICAgICAgICBjYXRlZ29yeV80QyA9IGNhdGVnb3J5KSAlPiUKICBkcGx5cjo6bXV0YXRlKGNoYW5nZV8yQyA9IChsYXllcl8yQyAtIGxheWVyX2N1cnJlbnQgLyBsYXllcl9jdXJyZW50KSAqIDEwMCwKICAgICAgICAgICAgICAgIGNoYW5nZV8yQ19BSSA9IGNhc2Vfd2hlbigKICAgICAgICAgICAgICAgICAgY2hhbmdlXzJDID49IC0yICYgY2hhbmdlXzJDIDwyIH4gJ05vIGNoYW5nZSB0byB3ZXR0ZXInLAogICAgICAgICAgICAgICAgICBjaGFuZ2VfMkMgPj0gLTEwICYgY2hhbmdlXzJDIDwgLTIgfiAnPi0yIHRvIC0xMCUnLAogICAgICAgICAgICAgICAgICBjaGFuZ2VfMkMgPj0gLTIwICYgY2hhbmdlXzJDIDwgLTEwIH4gJz4tMTAgdG8gLTIwJScsCiAgICAgICAgICAgICAgICAgIGNoYW5nZV8yQyA+PSAtNDAgJiBjaGFuZ2VfMkMgPCAtMjAgfiAnPi0yMCB0byAtNDAlJywKICAgICAgICAgICAgICAgICAgY2hhbmdlXzJDID49IC04MCAmIGNoYW5nZV8yQyA8IC00MCB+ICc+LTQwIHRvIC04MCUnLAogICAgICAgICAgICAgICAgICBjaGFuZ2VfMkMgPCAtODAgfiAnPC04MCUnKSwKICAgICAgICAgICAgICAgICAgY2hhbmdlXzRDID0gKGxheWVyXzRDIC0gbGF5ZXJfY3VycmVudCAvIGxheWVyX2N1cnJlbnQpICogMTAwLAogICAgICAgICAgICAgICAgY2hhbmdlXzRDX0FJID0gY2FzZV93aGVuKAogICAgICAgICAgICAgICAgICBjaGFuZ2VfNEMgPj0gLTIgJiBjaGFuZ2VfNEMgPDIgfiAnTm8gY2hhbmdlIHRvIHdldHRlcicsCiAgICAgICAgICAgICAgICAgIGNoYW5nZV80QyA+PSAtMTAgJiBjaGFuZ2VfNEMgPCAtMiB+ICc+LTIgdG8gLTEwJScsCiAgICAgICAgICAgICAgICAgIGNoYW5nZV80QyA+PSAtMjAgJiBjaGFuZ2VfNEMgPCAtMTAgfiAnPi0xMCB0byAtMjAlJywKICAgICAgICAgICAgICAgICAgY2hhbmdlXzRDID49IC00MCAmIGNoYW5nZV80QyA8IC0yMCB+ICc+LTIwIHRvIC00MCUnLAogICAgICAgICAgICAgICAgICBjaGFuZ2VfNEMgPj0gLTgwICYgY2hhbmdlXzRDIDwgLTQwIH4gJz4tNDAgdG8gLTgwJScsCiAgICAgICAgICAgICAgICAgIGNoYW5nZV80QyA8IC04MCB+ICc8LTgwJScKICAgICAgICAgICAgICAgICkpICU+JSAKICBmaWx0ZXIoY2F0ZWdvcnlfY3VycmVudCAhPSAiSHlwZXItYXJpZCIpICU+JQogIGRwbHlyOjptdXRhdGUoY2hhbmdlXzJDX0FJID0gZmFjdG9yKGNoYW5nZV8yQ19BSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc8LTgwJScsICc+LTQwIHRvIC04MCUnLCc+LTIwIHRvIC00MCUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJz4tMTAgdG8gLTIwJScsICc+LTIgdG8gLTEwJScsICdObyBjaGFuZ2UgdG8gd2V0dGVyJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpLAogICAgICAgICAgICAgICAgY2hhbmdlXzRDX0FJID0gZmFjdG9yKGNoYW5nZV80Q19BSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc8LTgwJScsICc+LTQwIHRvIC04MCUnLCc+LTIwIHRvIC00MCUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJz4tMTAgdG8gLTIwJScsICc+LTIgdG8gLTEwJScsICdObyBjaGFuZ2UgdG8gd2V0dGVyJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKQoKY2hhbmdlX2NvbCA8LSBjKCcjQjEzRjYzJywgJyNEMzVENjAnLCAnI0UzODU2NicsICcjRUVBQzdEJywgJyNGNUQxQTgnLCAnd2hpdGUnKQoKIyBGaWcgMUMgLSAyQyBEaWZmZXJlbmNlCmNoYW5nZV8yQ19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gQUlfbWVyZ2VkLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gY2hhbmdlXzJDX0FJKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNoYW5nZV9jb2wsIG5hLnZhbHVlID0gIndoaXRlIikgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbigiQ2hhbmdlIGluIGRyeW5lc3MgKCIqRGVsdGEqIkFJICsywrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpIAoKIyBGaWcgMWQgLSA0QyBEaWZmZXJlbmNlCmNoYW5nZV80Q19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gQUlfbWVyZ2VkLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gY2hhbmdlXzRDX0FJKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNoYW5nZV9jb2wsIG5hLnZhbHVlID0gIndoaXRlIikgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbigiQ2hhbmdlIGluIGRyeW5lc3MgKCIqRGVsdGEqIkFJICs0wrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpIAoKIyBGaWcgMWUgLSBEcnluZXNzIGFuZCBzcGVjaWVzIHJpY2huZXNzCmFyaWRfY29sXzIgPC0gYygiIzhFMDYzQiIsICIjQ0I2RDUzIiwgIiNFOTlBMkMiLCAiI0Y1RDU3OSIsICJsaWdodCBncmV5IikKc3BlY2llc19haV9wbG90IDwtIGFpX3NwX2RmICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBhcmlkaXR5LCB5ID0gc3BlY2llc19uLCBjb2xvdXIgPSBjYXRlZ29yeSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAyKSArCiAgY29vcmRfdHJhbnMoeCA9ICJzcXJ0IikgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYXJpZF9jb2xfMiwKICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDMpLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKDAsIDAuMDUsIDAuMiwgMC41LCAwLjY1KSkgKwogIHhsYWIoIlByZWNpcGl0YXRpb24gLyBFdmFwb3RyYW5zcGlyYXRpb24iKSArCiAgeWxhYigiU3BlY2llcyByaWNobmVzcyIpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkpCgojIEZpZyAxZiAtIERyeW5lc3MgYW5kIHNwZWNpZXMgcmljaG5lc3MgYnkgZWNvdHlwZQplY290eXBlX2FpX3Bsb3QgPC0gYWlfc3BfZGYgJT4lCiAgZHBseXI6OmZpbHRlcihhcmlkaXR5IDw9MykgJT4lCiAgZHBseXI6OnNlbGVjdChhcmlkaXR5LCBzcGVjaWVzX246c3RyZWFtX24pICU+JQogIHRpZHlyOjpwaXZvdF9sb25nZXIoIWFyaWRpdHksIG5hbWVzX3RvID0gImVjb3R5cGUiLCB2YWx1ZXNfdG8gPSAibWVhbiIpICU+JQogIGRwbHlyOjpmaWx0ZXIoZWNvdHlwZSAhPSAic3BlY2llc19uIikgJT4lCiAgZHJvcF9uYShtZWFuKSAlPiUKICBkcGx5cjo6bXV0YXRlKGVjb3R5cGUgPSBmYWN0b3IoZWNvdHlwZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoImZvc3NvcmlhbF9uIiwgImdyb3VuZF9uIiwgImFxdWF0aWNfbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhcmJvcmVhbF9uIiwgInNlbWlfYXFfbiIsICJzdHJlYW1fbiIpKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYXJpZGl0eSwgeSA9IGVjb3R5cGUsIGdyb3VwID0gZWNvdHlwZSwgZmlsbCA9IGVjb3R5cGUpKSArCiAgZ2dyaWRnZXM6OnN0YXRfZGVuc2l0eV9yaWRnZXMoc2NhbGUgPSAxLCByZWxfbWluX2hlaWdodCA9IDAuMDEsIGFscGhhID0gMC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX3ZpcmlkaXNfZCgpICsKICBzY2FsZV94X2NvbnRpbnVvdXModHJhbnMgPSAic3FydCIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCkgKwogIG15dGhlbWUoKQoKIyBGaWcgMWcgLSBDaGFuZ2UgaW4gc3BlY2llcyBBSQojIE1lcmdlIHN1bW1hcnkgZGF0YSBieSByb3cKYXJpZF9zcF9jb21iICAgICAgICAgIDwtIGRhdGEuZnJhbWUoYmluZF9yb3dzKGFpX3NwX3N1bSwgYWlfMkNfc3Bfc3VtLCBhaV80Q19zcF9zdW0pKQphcmlkX3NwX2NvbWIkc2NlbmFyaW8gPC0gZm9yY2F0czo6ZmN0X3JlbGV2ZWwoYXJpZF9zcF9jb21iJHNjZW5hcmlvLCAiQ3VycmVudCIpCgpzcGVjaWVzX29jY19wbG90IDwtIGFyaWRfc3BfY29tYiAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY2F0ZWdvcnksIHkgPSBsb2coYWxsX2ZyZXEpLCBncm91cCA9IHNjZW5hcmlvLCBjb2xvdXIgPSBzY2VuYXJpbywgc2hhcGUgPSBzY2VuYXJpbykpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuNSksIHNpemUgPSAxLjUpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiNGNUQ1NzkiLCAiI0NCNkQ1MyIsICIjOEUwNjNCIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gcHJldHR5KGxvZyhhcmlkX3NwX2NvbWIkYWxsX2ZyZXEpKSwgbGFiZWxzID0gcHJldHR5KGFyaWRfc3BfY29tYiRhbGxfZnJlcSkpICsKICB5bGFiKCIlIHNwZWNpZXMiKSArIHhsYWIoTlVMTCkgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCiMgRmlnIDEKcGxvdF9ncmlkKHNwZWNpZXNfYWlfcGxvdCwgZWNvdHlwZV9haV9wbG90LCBzcGVjaWVzX29jY19wbG90LCBhbGlnbiA9ICJ2IiwgbmNvbCA9IDMpICMgcGxvdCBpbiBiZXR3ZWVuLgoKY293cGxvdDo6cGxvdF9ncmlkKGFyaWRpdHlfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSwgCiAgICAgICAgICAgICAgICAgICBhbnVyYW5fcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSwgCiAgICAgICAgICAgICAgICAgICBjaGFuZ2VfMkNfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSwKICAgICAgICAgICAgICAgICAgIGNoYW5nZV80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpLAogICAgICAgICAgICAgICAgICAgYWxpZ24gPSAiaCIsIGF4aXMgPSAiYnQiLAogICAgICAgICAgICAgICAgICAgbmNvbCA9IDIpCmBgYAoKIyMgRmlndXJlIDIgLSBQRFNJIHJpc2sgey19CgpDcmVhdGUgcGxvdHMgZm9yIG1haW4gdGV4dCBmaWd1cmUgMi4KCmBgYHtyIEZpZyAyLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTksIGZpZy5zaG93PSdoaWRlJ30KUERTSV9yaXNrX3JvYiA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhQRFNJXzJDX2RpZmZfcmFzdCwgUERTSV80Q19kaWZmX3Jhc3QsIFBEU0lfZnJlcV9kaWZmLCBQRFNJX2R1cl9kaWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2FtcGxlKGFudXJhbl9zciwgUERTSV80Q19kaWZmX3Jhc3QpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNycyA9IHJvYl9wcm9qKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIApQRFNJX3Jpc2tfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV9yaXNrX3JvYikpICU+JQogIGRwbHlyOjpyZW5hbWUoInNwX24iID0gbGF5ZXIpICU+JQogIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKHNwX24pKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRlbHRhX2ludF8yQ19iaW4gPSBpZmVsc2UoZGVsdGFfaW50XzJDIDwgLTEsIDEsIDApLCAjIGRlbHRhX1BEU0kgPCAtMQogICAgICAgICBkZWx0YV9pbnRfNENfYmluID0gaWZlbHNlKGRlbHRhX2ludF80QyA8IC0xLCAxLCAwKSwgIyBkZWx0YV9QRFNJIDwgLTEKICAgICAgICAgZGVsdGFfZnJlcV8yQ19iaW4gPSBpZmVsc2UoZGVsdGFfZnJlcV8yQyA+MSwgMSwgMCksICMgbW9udGggPiAxCiAgICAgICAgIGRlbHRhX2ZyZXFfNENfYmluID0gaWZlbHNlKGRlbHRhX2ZyZXFfNEMgPjEsIDEsIDApLCAjIG1vbnRoID4gMQogICAgICAgICBkZWx0YV9kdXJfMkNfYmluID0gaWZlbHNlKGRlbHRhX2R1cl8yQyA+MSwgMSwgMCksICMgbW9udGggPiAxCiAgICAgICAgIGRlbHRhX2R1cl80Q19iaW4gPSBpZmVsc2UoZGVsdGFfZHVyXzRDID4xLCAxLCAwKSkgJT4lICMgbW9udGggPiAxIAogIGRwbHlyOjpyb3d3aXNlKCkgJT4lCiAgZHBseXI6Om11dGF0ZShjb3VudF8yQyA9IHN1bShkZWx0YV9pbnRfMkNfYmluLCBkZWx0YV9mcmVxXzJDX2JpbiwgZGVsdGFfZHVyXzJDX2JpbiwgbmEucm0gPSBUKSwKICAgICAgICAgCiAgICAgICAgIGNvdW50XzRDID0gc3VtKGRlbHRhX2ludF80Q19iaW4sIGRlbHRhX2ZyZXFfNENfYmluLCBkZWx0YV9kdXJfNENfYmluLCBuYS5ybSA9IFQpLAogICAgICAgICByaXNrXzJDICA9IHNwX24gKiBjb3VudF8yQywKICAgICAgICAgcmlza180QyAgPSBzcF9uICogY291bnRfNEMsCiAgICAgICAgIGNvdW50XzJDID0gZmFjdG9yKGNvdW50XzJDLCBsZXZlbHMgPSBjKCIzIiwgIjIiLCAiMSIpKSwKICAgICAgICAgY291bnRfNEMgPSBmYWN0b3IoY291bnRfNEMsIGxldmVscyA9IGMoIjMiLCAiMiIsICIxIikpCiAgICAgICAgICkgJT4lCiAgZGF0YS5mcmFtZSgpCgojIFBsb3QKUERTSV9yaXNrXzJDX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBQRFNJX3Jpc2tfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBjb3VudF8yQykpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJSZWRPciIsIHJldiA9IEYpICsKICBnZ25ld3NjYWxlOjpuZXdfc2NhbGUoImZpbGwiKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGhpbGxfZGYgJT4lIGZpbHRlcihoaWxsIDw9IDAuNjQ1KSwgYWVzKGxvbiwgbGF0LCBmaWxsID0gaGlsbCwgYWxwaGEgPSBoaWxsKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImJsYWNrIiwgaGlnaCA9ICJncmV5IikgKwogIHNjYWxlX2FscGhhX2NvbnRpbnVvdXModHJhbnMgPSAicmV2ZXJzZSIpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZShleHByZXNzaW9uKCIrMsKwQyBieSAyMDgwLTIxMDAiKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpQRFNJX3Jpc2tfNENfcGxvdCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IFBEU0lfcmlza19kZiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGNvdW50XzRDKSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGVfc2VxdWVudGlhbChwYWxldHRlID0gIlJlZE9yIiwgcmV2ID0gRikgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKGV4cHJlc3Npb24oIis0wrBDIGJ5IDIwODAtMjEwMCIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCnNwXzJDX3Bsb3QgPC0gUERTSV9yaXNrX2RmICU+JQogIGRwbHlyOjptdXRhdGUocmlza18yQ19jYXQgPSBjYXNlX3doZW4oCiAgICByaXNrXzJDID09IDAgfiAnMCcsCiAgICByaXNrXzJDID4gMCAmIHJpc2tfMkMgPD0xIH4gJzwxJywKICAgIHJpc2tfMkMgPiAxICYgcmlza18yQyA8IDUgfiAnPjEgdG8gNScsCiAgICByaXNrXzJDID49IDUgJiByaXNrXzJDIDwgMTAgfiAnPjUgdG8gMTAnLAogICAgcmlza18yQyA+PSAxMCAmIHJpc2tfMkMgPCAyMCB+ICc+MTAgdG8gMjAnLAogICAgcmlza18yQyA+PSAyMCAmIHJpc2tfMkMgPCAxMDAgfiAnPjIwIHRvIDEwMCcsCiAgICByaXNrXzJDID49IDEwMCAmIHJpc2tfMkMgPCAyMDAgfiAnPjEwMCB0byAyMDAnLAogICAgcmlza18yQyA+IDIwMCB+ICc+MjAwJyksCiAgICByaXNrXzJDID0gbmFfaWYocmlza18yQywgMCksCiAgICByaXNrXzJDX2NhdCA9IGZhY3RvcihyaXNrXzJDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc+MjAwJywnPjEwMCB0byAyMDAnLCAnPjIwIHRvIDEwMCcsJz4xMCB0byAyMCcsICc+NSB0byAxMCcsICc+MSB0byA1JywgJzwxJykpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IHJpc2tfMkNfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfZGlzY3JldGVfc2VxdWVudGlhbChwYWxldHRlID0gIkhlYXQiLCByZXYgPSBGKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpzcF80Q19wbG90IDwtIFBEU0lfcmlza19kZiAlPiUKICBkcGx5cjo6bXV0YXRlKHJpc2tfNENfY2F0ID0gY2FzZV93aGVuKAogICAgcmlza180QyA9PSAwIH4gJzAnLAogICAgcmlza180QyA+IDAgJiByaXNrXzRDIDw9MSB+ICc8MScsCiAgICByaXNrXzRDID4gMSAmIHJpc2tfNEMgPCA1IH4gJz4xIHRvIDUnLAogICAgcmlza180QyA+PSA1ICYgcmlza180QyA8IDEwIH4gJz41IHRvIDEwJywKICAgIHJpc2tfNEMgPj0gMTAgJiByaXNrXzRDIDwgMjAgfiAnPjEwIHRvIDIwJywKICAgIHJpc2tfNEMgPj0gMjAgJiByaXNrXzRDIDwgMTAwIH4gJz4yMCB0byAxMDAnLAogICAgcmlza180QyA+PSAxMDAgJiByaXNrXzRDIDwgMjAwIH4gJz4xMDAgdG8gMjAwJywKICAgIHJpc2tfNEMgPiAyMDAgfiAnPjIwMCcpLAogICAgcmlza180QyA9IG5hX2lmKHJpc2tfNEMsIDApLAogICAgcmlza180Q19jYXQgPSBmYWN0b3Iocmlza180Q19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjIwMCcsJz4xMDAgdG8gMjAwJywgJz4yMCB0byAxMDAnLCc+MTAgdG8gMjAnLCAnPjUgdG8gMTAnLCAnPjEgdG8gNScsICc8MScpKSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSByaXNrXzRDX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJIZWF0IiwgcmV2ID0gRikgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjFlNSwgODVlNSksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTVlNiwgMTZlNiksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKY293cGxvdDo6cGxvdF9ncmlkKFBEU0lfcmlza18yQ19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICAgICAgICAgICAgICAgICAgIFBEU0lfcmlza180Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICAgICAgICAgICAgICAgICAgIHNwXzJDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogICAgICAgICAgICAgICAgICAgc3BfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgICAgICAgICAgICAgICAgICBuY29sID0gMiwKICAgICAgICAgICAgICAgICAgIGFsaWduID0gImgiLCBheGlzID0gImJ0IiwgbGFiZWxzID0gYygnYScsICdiJywgJ2MnLCAnZCcpKQoKI1BEU0lfcmlza19kZiAlPiUKICAjZ3JvdXBfYnkoY291bnRfMkMpICU+JQogICNzdW1tYXJpc2UobGVuZ3RoID0gbGVuZ3RoKGNvdW50XzJDKSkgJT4lCiAgI211dGF0ZShmcmVxID0gbGVuZ3RoIC8gbGVuZ3RoKFBEU0lfcmlza19kZiRjb3VudF8yQykgKiAxMDApCgojUERTSV9yaXNrX2RmICU+JQogICNncm91cF9ieShjb3VudF80QykgJT4lCiAgI3N1bW1hcmlzZShsZW5ndGggPSBsZW5ndGgoY291bnRfNEMpKSAlPiUKICAjbXV0YXRlKGZyZXEgPSBsZW5ndGggLyBsZW5ndGgoUERTSV9yaXNrX2RmJGNvdW50XzRDKSAqIDEwMCkKYGBgIAoKIyMgRmlndXJlIDMgLSBXYXRlciBsb3NzIHJpc2sgey19CgpSdW4gdGhlIGBlY3RvdGhlcm1gIGZ1bmN0aW9uIGZyb20gKk5pY2hlTWFwUiogZm9yIGFsbCAxMiBtb250aHMgZnJvbSB0aGUgVGVycmEgQ2xpbWF0ZSByYXN0ZXIgZmlsZXMgY29udGFpbmluZyB0aGUgbWVhbiB3aW5kIHNwZWVkIChtIHNeLTFeKSwgbWF4aW11bSBhaXIgdGVtcGVyYXR1cmUgKMKwQyksIGFuZCB2YXBvdXIgcHJlc3N1cmUgZGVmaWNpdCAoVlBEOyBrUGEpIGZvciB0aGUgY3VycmVudCAoMTk4MSB0byAyMDEwKSwgKzLCsEMgYW5kICs0wrBDIHNjZW5hcmlvLiBGcm9tIHRoZSBlY290aGVybSBtb2RlbCwgd2UgZXh0cmFjdGVkIHRoZSBFV0wgKGcgaF4tMV4pIGZvciBlYWNoIHJhc3RlciBwaXhlbCB0byBkZXRlcm1pbmUgdGhlIHNwYXRpYWwgdmFyaWF0aW9uIGluIEVXTC4KCmBgYHtyIGdsb2JfZXdsLCBldmFsPUZBTFNFLCBlY2hvPVR9CiMjIEN1cnJlbnQgIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmVsZXYgICAgICA8LSBnZXREYXRhKCJ3b3JsZGNsaW0iLCB2YXIgPSAiYWx0IiwgcmVzID0gMi41KQp3c19mdWxsICAgPC0gIHJhc3Rlcjo6YnJpY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ1RlcnJhQ2xpbWF0ZTE5ODEyMDEwX3dzLm5jJykpICMgMTBtLCBtL3MKdG1heF9mdWxsIDwtIHJhc3Rlcjo6YnJpY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ1RlcnJhQ2xpbWF0ZTE5ODEyMDEwX3RtYXgubmMnKSkgIyAybSwgZGVnIEMKdnBkX2Z1bGwgIDwtIHJhc3Rlcjo6YnJpY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ1RlcnJhQ2xpbWF0ZTE5ODEyMDEwX3ZwZC5uYycpKSAjIDJtLCBrcGEKVGJzICAgICAgIDwtIGNyb3AodG1heF9mdWxsLCBleHRlbnQoZWxldikpCkVXTHMgICAgICA8LSBUYnMgCgojIFJ1biBlY3RvdGhlcm0gbW9kZWwgZm9yIGVhY2ggbW9udGggYW5kIHNhdmUgb24gbG9jYWwgZHJpdmUgKGN1cnJlbnQgc2NlbmFyaW8pCmZvcihtb250aCBpbiAxOjEyKXsKICAjIFRlbXBlcmF0dXJlCiAgVGEudyAgIDwtIGNyb3AodG1heF9mdWxsW1ttb250aF1dLCBleHRlbnQoZWxldikpCiAgZXNhdCAgIDwtIFZBUFBSUyhUYS53KQogICMgUkgKICBlICAgICAgPC0gZXNhdCAtIGNyb3AodnBkX2Z1bGxbW21vbnRoXV0sIGV4dGVudChlbGV2KSkgKiAxMDAwCiAgUkgudyAgIDwtIGUgLyBlc2F0ICogMTAwCiAgUkgud1tSSC53IDwgMF0gPC0gMAogICMgV2luZCBzcGVlZAogIFdpbmQudyA8LSBjcm9wKHdzX2Z1bGxbW21vbnRoXV0sIGV4dGVudChlbGV2KSkKICBWc3RhciAgPC0gMC40ICogV2luZC53IC8gbG9nKCgxMDAgLyAwLjE1KSArIDEpICMgZnJpY3Rpb24gdmVsb2NpdHkKICBXaW5kLncgPC0gMi41ICogVnN0YXIgKiBsb2coKDEgLyAwLjE1KSArIDEpICMgY29ycmVjdCBmb3IgcmVmZXJlbmNlIGhlaWdodCAoMTAgbSkgdG8gZ3JvdW5kIGxldmVsICgxIGNtKSBhc3N1bWluZyBsZXZlbCBncm91bmQKICAjIGNvbXB1dGUgYXRtb3NwaGVyaWMgcHJlc3N1cmUgKGtQYSkKICBQLncgPC0gMTAxMzI1ICogKCgxIC0gKDAuMDA2NSAqIGVsZXYgLyAyODgpKSBeICgxIC8gMC4xOTAyODQpKSAvIDEwMDAKICAKICAjIEdldCByYXN0ZXIgdmFsdWVzCiAgVGEgIDwtIGdldFZhbHVlcyhUYS53KQogIFJIICA8LSBnZXRWYWx1ZXMoUkgudykKICBQICAgPC0gZ2V0VmFsdWVzKFAudykKICBQYSAgPC0gZ2V0VmFsdWVzKGUpCiAgd3MgIDwtIGdldFZhbHVlcyhXaW5kLncpCiAgUFshaXMubmEoVGEpICYgaXMubmEoUCldIDwtIDEwMS4zMjUKICBUYTIgPC0gVGFbIWlzLm5hKFRhKV0KICBSSDIgPC0gUkhbIWlzLm5hKFRhKV0KICBQMiAgPC0gUFshaXMubmEoVGEpXQogIHdzMiA8LSB3c1shaXMubmEoVGEpXQogIFBhMiA8LSBQYVshaXMubmEoVGEpXQogIAogIGRpdiA8LSAxMAogIFR3YiA8LSBUYTJbMTpmbG9vcihsZW5ndGgoVGEyKSAvIGRpdildCiAgbWljcm9fYmFzZSA8LSBtaWNyb19nbG9iYWwoKQogIAogIGZvcihrIGluIDE6ZGl2KXsKICAgIG1pY3JvIDwtIG1pY3JvX2Jhc2UKICAgIGlmKGsgPT0gMSl7CiAgICAgIGV4dHJhIDwtIHJvdW5kKDI0IC0gKGxlbmd0aChUd2IpIC8gMjQpJSUxICogMjQsIDApCiAgICAgIFR3YjQgIDwtIGMoVHdiLCByZXAoVGEyWzFdLCBleHRyYSkpCiAgICAgIHN0YXJ0IDwtIDEKICAgICAgZW5kICAgPC0gbGVuZ3RoKFR3YikKICAgIH0KICAgIGlmKGsgPiAxICYgayA8IGRpdil7CiAgICAgIGZhY3QgIDwtIChsZW5ndGgoVHdiKSAqIChrIC0gMSkgKyBrIC0gMSkKICAgICAgVHdiNCAgPC0gVGEyW2ZhY3Q6KGZhY3QgKyBsZW5ndGgoVHdiKSldCiAgICAgIGV4dHJhIDwtIHJvdW5kKDI0IC0gKGxlbmd0aChUd2I0KSAvIDI0KSUlMSAqIDI0LCAwKQogICAgICBUd2I0ICA8LSBjKFR3YjQsIHJlcChUYTJbMV0sIGV4dHJhKSkKICAgICAgc3RhcnQgPC0gZmFjdAogICAgICBlbmQgICA8LSBmYWN0ICsgbGVuZ3RoKFR3YikKICAgIH0gICAgICAgIAogICAgaWYoayA9PSBkaXYpewogICAgICBmYWN0ICA8LSAobGVuZ3RoKFR3YikgKiAoayAtIDEpICsgayAtIDEpCiAgICAgIFR3YjQgIDwtIFRhMltmYWN0Omxlbmd0aChUYTIpXQogICAgICBleHRyYSA8LSByb3VuZCgyNCAtIChsZW5ndGgoVHdiNCkgLyAyNCklJTEgKiAyNCwgMCkKICAgICAgVHdiNCAgPC0gYyhUd2I0LCByZXAoVGEyWzFdLCBleHRyYSkpCiAgICAgIHN0YXJ0IDwtIGZhY3QKICAgICAgZW5kICAgPC0gbGVuZ3RoKFRhMikKICAgIH0gCiAgICAKICAgIHNvaWxuYW1lcyAgICAgPC0gZGltbmFtZXMobWljcm8kc29pbCkKICAgIG1ldG91dG5hbWVzICAgPC0gZGltbmFtZXMobWljcm8kbWV0b3V0KQogICAgdGNvbmRuYW1lcyAgICA8LSBkaW1uYW1lcyhtaWNybyR0Y29uZCkKICAgIHNwZWNoZWF0bmFtZXMgPC0gZGltbmFtZXMobWljcm8kc3BlY2hlYXQpCiAgICBkZW5zaXRuYW1lcyAgIDwtIGRpbW5hbWVzKG1pY3JvJGRlbnNpdCkKICAgIHBsYW50bmFtZXMgICAgPC0gZGltbmFtZXMobWljcm8kcGxhbnQpCiAgICAKICAgIG1pY3JvJG1ldG91dCAgIDwtIHQoYXJyYXkobWljcm8kbWV0b3V0WzEsXSwgZGltID0gYyhuY29sKG1pY3JvJG1ldG91dCksIGxlbmd0aChUd2I0KSkpKQogICAgZGltbmFtZXMobWljcm8kbWV0b3V0KSA8LSBtZXRvdXRuYW1lcwogICAgbWljcm8kc29pbCAgICAgPC0gdChhcnJheShtaWNybyRzb2lsWzEsXSwgZGltID0gYyhuY29sKG1pY3JvJHNvaWwpLCBsZW5ndGgoVHdiNCkpKSkKICAgIGRpbW5hbWVzKG1pY3JvJHNvaWwpIDwtIHNvaWxuYW1lcwogICAgbWljcm8kdGNvbmQgICAgPC0gdChhcnJheShtaWNybyR0Y29uZFsxLF0sIGRpbSA9IGMobmNvbChtaWNybyR0Y29uZCksIGxlbmd0aChUd2I0KSkpKQogICAgZGltbmFtZXMobWljcm8kdGNvbmQpIDwtIHRjb25kbmFtZXMKICAgIG1pY3JvJHNwZWNoZWF0IDwtIHQoYXJyYXkobWljcm8kc3BlY2hlYXRbMSxdLCBkaW0gPSBjKG5jb2wobWljcm8kc3BlY2hlYXQpLCBsZW5ndGgoVHdiNCkpKSkKICAgIGRpbW5hbWVzKG1pY3JvJHNwZWNoZWF0KSA8LSBzcGVjaGVhdG5hbWVzICAKICAgIG1pY3JvJGRlbnNpdCAgIDwtIHQoYXJyYXkobWljcm8kZGVuc2l0WzEsXSwgZGltID0gYyhuY29sKG1pY3JvJGRlbnNpdCksIGxlbmd0aChUd2I0KSkpKQogICAgZGltbmFtZXMobWljcm8kZGVuc2l0KSA8LSBkZW5zaXRuYW1lcyAgICAgIAogICAgbWljcm8kcGxhbnQgICAgPC0gdChhcnJheShtaWNybyRwbGFudFsxLF0sIGRpbSA9IGMobmNvbChtaWNybyRwbGFudCksIGxlbmd0aChUd2I0KSkpKQogICAgZGltbmFtZXMobWljcm8kcGxhbnQpIDwtIHBsYW50bmFtZXMgCiAgICAKICAgIG1pY3JvJHNoYWRtZXQgPC0gbWljcm8kbWV0b3V0CiAgICBtaWNybyRzaGFkc29pbCA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRodW1pZCA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRzaGFkaHVtaWQgPC0gbWljcm8kc29pbAogICAgbWljcm8kc29pbHBvdCA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRzaGFkcG90IDwtIG1pY3JvJHNvaWwKICAgIG1pY3JvJHNvaWxtb2lzdCA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRzaGFkbW9pc3QgPC0gbWljcm8kc29pbAogICAgbWljcm8kc2hhZHRjb25kIDwtIG1pY3JvJHRjb25kCiAgICBtaWNybyRzaGFkZGVuc2l0IDwtIG1pY3JvJGRlbnNpdAogICAgbWljcm8kc2hhZHNwZWNoZWF0IDwtIG1pY3JvJHNwZWNoZWF0CiAgICBtaWNybyRzaGFkcGxhbnQgPC0gbWljcm8kcGxhbnQKICAgIG1pY3JvJFJBSU5GQUxMIDwtIHJlcCgwLCBsZW5ndGgoVHdiNCkvMjQpCiAgICBtaWNybyRtaW5zaGFkZSA8LSByZXAoMCwgbGVuZ3RoKFR3YjQpLzI0KQogICAgbWljcm8kbWF4c2hhZGUgPC0gcmVwKDkwLCBsZW5ndGgoVHdiNCkvMjQpCiAgICBtaWNybyRueWVhcnMgPC0gY2VpbGluZyhsZW5ndGgoVHdiNCkvMjQvMzY1KQogICAgCiAgICAjIHJlcGxhY2UgZmlyc3QgbGluZSBvZiBtaWNyb2NsaW1hdGUgaW5wdXQgd2l0aCBhaXIgdGVtcGVyYXR1cmUgYW5kIGh1bWlkaXR5IGF0IHdoaWNoIHRvIGNvbXB1dGUgVHcKICAgIG1pY3JvJG1ldG91dFsxOmxlbmd0aChUd2I0KSxjKDMsNCwxNCldIDwtIGMoVGEyW3N0YXJ0OmVuZF0sIHJlcChUYTJbMV0sIGV4dHJhKSkgIyBzZXQgYWlyIGFuZCBza3kgdGVtcGVyYXR1cmUKICAgIG1pY3JvJG1ldG91dFsxOmxlbmd0aChUd2I0KSxjKDUsNildIDwtIGMoUkgyW3N0YXJ0OmVuZF0sIHJlcChSSDJbMV0sIGV4dHJhKSkgIyBzZXQgcmVsYXRpdmUgaHVtaWRpdHkKICAgICMgbWljcm8kbWV0b3V0WzE6bGVuZ3RoKFR3YjMpLGMoNyw4KV0gPC0gMC4wNSAjIHNldCB3aW5kIHNwZWVkIHRvIGxvdyAoc2Vuc2l0aXZlIHRvIHRoaXMpCiAgICBtaWNybyRzb2lsWzE6bGVuZ3RoKFR3YjQpLDNdIDwtIGMoVGEyW3N0YXJ0OmVuZF0sIHJlcChUYTJbMV0sIGV4dHJhKSkgIyBzZXQgc3VyZmFjZSBzb2lsIHRlbXBlcmF0dXJlIHRvIGFpciB0ZW1wZXJhdHVyZQogICAgbWljcm8kbWV0b3V0WzE6bGVuZ3RoKFR3YjQpLCAyXSA8LSByZXAoc2VxKDAsIDIzICogNjAsIDYwKSwgbGVuZ3RoKFRhMikvMjQgKyAxKVsxOmxlbmd0aChUd2I0KV0KICAgICNtaWNybyRtZXRvdXRbMTpsZW5ndGgoVHdiMyksIDFdIDwtIHNlcSgwLCAyMyAqIDYwLCA2MClbMTpsZW5ndGgoVHdiMyldCiAgICBwcmVzaHIgPC0gYyhQMltzdGFydDplbmRdLCByZXAoUDJbMV0sIGV4dHJhKSkqMTAwMCAgICAgICAgICAKICAgIAogICAgbWljcm8kbWV0b3V0WzE6bGVuZ3RoKFR3YjQpLGMoNyw4KV0gPC0gYyh3czJbc3RhcnQ6ZW5kXSwgcmVwKHdzMlsxXSwgZXh0cmEpKSAjIHNldCB3aW5kIHNwZWVkICAgIAogICAgCiAgICAjIHJ1biB0aGUgZWN0b3RoZXJtIG1vZGVsIAogICAgbWVzc2FnZShwYXN0ZSgncnVubmluZyBlY3RvdGhlcm0gc2ltdWxhdGlvbiBmb3IgbW9udGggJyxtb250aCwnIGZvciAnLCBsZW5ndGgoVHdiNCksJyBzaXRlcyBcbicpKQogICAgcHRtIDwtIHByb2MudGltZSgpICMgU3RhcnQgdGltaW5nCiAgICBnYygpCiAgICBlY3RvIDwtIGVjdG90aGVybShXd19nID0gOC43LAogICAgICAgICAgICAgICAgICAgICAgbGl2ZSA9IDAsCiAgICAgICAgICAgICAgICAgICAgICBwY3Rfd2V0ID0gODcsCiAgICAgICAgICAgICAgICAgICAgICBzaGFwZSA9IDQsICMgZnJvZwogICAgICAgICAgICAgICAgICAgICAgcHJlc2hyID0gcHJlc2hyKQogICAgbWVzc2FnZShwYXN0ZTAoJ3J1bnRpbWUgJywgKHByb2MudGltZSgpIC0gcHRtKVszXSwgJyBzZWNvbmRzJykpICMgU3RvcCB0aGUgY2xvY2sKICAgIGdjKCkKICAgIGVudmlyb24gPC0gYXMuZGF0YS5mcmFtZShlY3RvJGVudmlyb24pCiAgICBtYXNiYWwgIDwtIGFzLmRhdGEuZnJhbWUoZWN0byRtYXNiYWwpCiAgICBpZihrID09IDEpewogICAgICBUYi5lY3RvdGhlcm0gIDwtIGVudmlyb24kVENbMToobnJvdyhlbnZpcm9uKSAtIGV4dHJhKV0KICAgICAgRVdMLmVjdG90aGVybSA8LSBtYXNiYWwkSDJPQ3V0X2dbMToobnJvdyhtYXNiYWwpIC0gZXh0cmEpXQogICAgfWVsc2V7CiAgICAgIFRiLmVjdG90aGVybSAgPC0gYyhUYi5lY3RvdGhlcm0sIGVudmlyb24kVENbMToobnJvdyhlbnZpcm9uKSAtIGV4dHJhKV0pCiAgICAgIEVXTC5lY3RvdGhlcm0gPC0gYyhFV0wuZWN0b3RoZXJtLCBtYXNiYWwkSDJPQ3V0X2dbMToobnJvdyhtYXNiYWwpIC0gZXh0cmEpXSkKICAgIH0KICB9CiAgVGIyICAgICA8LSBUYQogIFRiMlshaXMubmEoVGEpXSA8LSBUYi5lY3RvdGhlcm0KICBUYi5ncmlkIDwtIFRhLncKICBUYi5ncmlkIDwtIHNldFZhbHVlcyhUYi5ncmlkLCBUYjIpCiAgI3Bsb3QoVGIuZ3JpZCkKICAjbWFwKCd3b3JsZCcsIGFkZCA9IFRSVUUpCiAgCiAgRVdMMiA8LSBUYQogIEVXTDJbIWlzLm5hKFRhKV0gPC0gRVdMLmVjdG90aGVybQogIEVXTC5ncmlkIDwtIFRhLncKICBFV0wuZ3JpZCA8LSBzZXRWYWx1ZXMoRVdMLmdyaWQsIEVXTDIpCiAgI3Bsb3QoRVdMLmdyaWQpCiAgRVdMLmdyaWRbVGIuZ3JpZCA8PSAwXSA8LSBOQQogICNtYXAoJ3dvcmxkJywgYWRkID0gVFJVRSkKCiAgd3JpdGVSYXN0ZXIoRVdMLmdyaWQsIGZpbGUgPSBwYXN0ZTAoJ0VXTF8nLG1vbnRoLCcubmMnKSwgb3ZlcndyaXRlID0gVFJVRSkKfSAKCiMjICsyQyAjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KdG1heF9mdWxsXzJDIDwtIHJhc3Rlcjo6YnJpY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ1RlcnJhQ2xpbWF0ZTJDX3RtYXgubmMnKSkgIyAybSwgZGVnIEMKZXNfa1BhXzJDICAgIDwtIHRtYXhfZnVsbF8yQwp2YWx1ZXMoZXNfa1BhXzJDKSA8LSAwLjYxMSAqIGV4cCgyNTAwMDAwIC8gNDYxLjUgKiAoIDEgLyAyNzMgLSAxIC8gKHZhbHVlcyh0bWF4X2Z1bGxfMkMpICsgMjczLjE1KSkpCgojIEFjdHVhbCB2YXBvdXIgcHJlc3N1cmUKZWFfa1BhIDwtIHJhc3Rlcjo6YnJpY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ1RlcnJhQ2xpbWF0ZTE5ODEyMDEwX3ZhcC5uYycpKQplYV9rUGFfMkMgPC0gZWFfa1BhCnZhbHVlcyhlYV9rUGFfMkMpIDwtIHZhbHVlcyhlYV9rUGFfMkMpICogMC45CgojIENhbGN1bGF0ZSBWUEQgKGtQYSkKdnBkX2Z1bGxfMkMgPC0gZWFfa1BhXzJDCnZhbHVlcyh2cGRfZnVsbF8yQykgPC0gdmFsdWVzKGVzX2tQYV8yQykgLSB2YWx1ZXMoZWFfa1BhXzJDKQoKVGJzIDwtIGNyb3AodG1heF9mdWxsXzJDLCBleHRlbnQoZWxldikpCkVXTHMgPC0gVGJzIAoKIyBSdW4gZWN0b3RoZXJtIG1vZGVsIGZvciBlYWNoIG1vbnRoIGFuZCBzYXZlIG9uIGxvY2FsIGRyaXZlICgrMkMgc2NlbmFyaW8pCmZvcihtb250aCBpbiAxOjEyKXsKICBUYS53ICAgPC0gY3JvcCh0bWF4X2Z1bGxfMkNbW21vbnRoXV0sIGV4dGVudChlbGV2KSkKICBlc2F0ICAgPC0gVkFQUFJTKFRhLncpCiAgZSAgICAgIDwtIGVzYXQgLSBjcm9wKHZwZF9mdWxsXzJDW1ttb250aF1dLCBleHRlbnQoZWxldikpICogMTAwMAogIFJILncgICA8LSBlIC8gZXNhdCAqIDEwMAogIFJILndbUkgudyA8IDBdIDwtIDAKICBXaW5kLncgPC0gY3JvcCh3c19mdWxsW1ttb250aF1dLCBleHRlbnQoZWxldikpCiAgVnN0YXIgIDwtIDAuNCAqIFdpbmQudyAvIGxvZygoMTAwIC8gMC4xNSkgKyAxKSAjIGZyaWN0aW9uIHZlbG9jaXR5CiAgV2luZC53IDwtIDIuNSAqIFZzdGFyICogbG9nKCgxIC8gMC4xNSkgKyAxKSAjIGNvcnJlY3QgZm9yIHJlZmVyZW5jZSBoZWlnaHQgKDEwIG0pIHRvIGdyb3VuZCBsZXZlbCAoMSBjbSkgYXNzdW1pbmcgbGV2ZWwgZ3JvdW5kCiAgIyBjb21wdXRlIGF0bW9zcGhlcmljIHByZXNzdXJlIChrUGEpCiAgUC53IDwtIDEwMTMyNSAqICgoMSAtICgwLjAwNjUgKiBlbGV2IC8gMjg4KSkgXiAoMSAvIDAuMTkwMjg0KSkgLyAxMDAwCiAgCiAgVGEgIDwtIGdldFZhbHVlcyhUYS53KQogIFJIICA8LSBnZXRWYWx1ZXMoUkgudykKICBQICAgPC0gZ2V0VmFsdWVzKFAudykKICBQYSAgPC0gZ2V0VmFsdWVzKGUpCiAgd3MgIDwtIGdldFZhbHVlcyhXaW5kLncpCiAgUFshaXMubmEoVGEpICYgaXMubmEoUCldIDwtIDEwMS4zMjUKICBUYTIgPC0gVGFbIWlzLm5hKFRhKV0KICBSSDIgPC0gUkhbIWlzLm5hKFRhKV0KICBQMiAgPC0gUFshaXMubmEoVGEpXQogIHdzMiA8LSB3c1shaXMubmEoVGEpXQogIFBhMiA8LSBQYVshaXMubmEoVGEpXQogIAogIGRpdiA8LSAxMAogIFR3YiA8LSBUYTJbMTpmbG9vcihsZW5ndGgoVGEyKSAvIGRpdildCiAgbWljcm9fYmFzZSA8LSBtaWNyb19nbG9iYWwoKQogIAogIGZvcihrIGluIDE6ZGl2KXsKICAgIG1pY3JvIDwtIG1pY3JvX2Jhc2UKICAgIGlmKGsgPT0gMSl7CiAgICAgIGV4dHJhIDwtIHJvdW5kKDI0IC0gKGxlbmd0aChUd2IpIC8gMjQpJSUxICogMjQsIDApCiAgICAgIFR3YjQgIDwtIGMoVHdiLCByZXAoVGEyWzFdLCBleHRyYSkpCiAgICAgIHN0YXJ0IDwtIDEKICAgICAgZW5kICAgPC0gbGVuZ3RoKFR3YikKICAgIH0KICAgIGlmKGsgPiAxICYgayA8IGRpdil7CiAgICAgIGZhY3QgIDwtIChsZW5ndGgoVHdiKSAqIChrIC0gMSkgKyBrIC0gMSkKICAgICAgVHdiNCAgPC0gVGEyW2ZhY3Q6KGZhY3QgKyBsZW5ndGgoVHdiKSldCiAgICAgIGV4dHJhIDwtIHJvdW5kKDI0IC0gKGxlbmd0aChUd2I0KSAvIDI0KSUlMSAqIDI0LCAwKQogICAgICBUd2I0ICA8LSBjKFR3YjQsIHJlcChUYTJbMV0sIGV4dHJhKSkKICAgICAgc3RhcnQgPC0gZmFjdAogICAgICBlbmQgICA8LSBmYWN0ICsgbGVuZ3RoKFR3YikKICAgIH0gICAgICAgIAogICAgaWYoayA9PSBkaXYpewogICAgICBmYWN0ICA8LSAobGVuZ3RoKFR3YikgKiAoayAtIDEpICsgayAtIDEpCiAgICAgIFR3YjQgIDwtIFRhMltmYWN0Omxlbmd0aChUYTIpXQogICAgICBleHRyYSA8LSByb3VuZCgyNCAtIChsZW5ndGgoVHdiNCkgLyAyNCklJTEgKiAyNCwgMCkKICAgICAgVHdiNCAgPC0gYyhUd2I0LCByZXAoVGEyWzFdLCBleHRyYSkpCiAgICAgIHN0YXJ0IDwtIGZhY3QKICAgICAgZW5kICAgPC0gbGVuZ3RoKFRhMikKICAgIH0gCiAgICAKICAgIHNvaWxuYW1lcyAgICAgPC0gZGltbmFtZXMobWljcm8kc29pbCkKICAgIG1ldG91dG5hbWVzICAgPC0gZGltbmFtZXMobWljcm8kbWV0b3V0KQogICAgdGNvbmRuYW1lcyAgICA8LSBkaW1uYW1lcyhtaWNybyR0Y29uZCkKICAgIHNwZWNoZWF0bmFtZXMgPC0gZGltbmFtZXMobWljcm8kc3BlY2hlYXQpCiAgICBkZW5zaXRuYW1lcyAgIDwtIGRpbW5hbWVzKG1pY3JvJGRlbnNpdCkKICAgIHBsYW50bmFtZXMgICAgPC0gZGltbmFtZXMobWljcm8kcGxhbnQpCiAgICAKICAgIG1pY3JvJG1ldG91dCAgIDwtIHQoYXJyYXkobWljcm8kbWV0b3V0WzEsXSwgZGltID0gYyhuY29sKG1pY3JvJG1ldG91dCksIGxlbmd0aChUd2I0KSkpKQogICAgZGltbmFtZXMobWljcm8kbWV0b3V0KSA8LSBtZXRvdXRuYW1lcwogICAgbWljcm8kc29pbCAgICAgPC0gdChhcnJheShtaWNybyRzb2lsWzEsXSwgZGltID0gYyhuY29sKG1pY3JvJHNvaWwpLCBsZW5ndGgoVHdiNCkpKSkKICAgIGRpbW5hbWVzKG1pY3JvJHNvaWwpIDwtIHNvaWxuYW1lcwogICAgbWljcm8kdGNvbmQgICAgPC0gdChhcnJheShtaWNybyR0Y29uZFsxLF0sIGRpbSA9IGMobmNvbChtaWNybyR0Y29uZCksIGxlbmd0aChUd2I0KSkpKQogICAgZGltbmFtZXMobWljcm8kdGNvbmQpIDwtIHRjb25kbmFtZXMKICAgIG1pY3JvJHNwZWNoZWF0IDwtIHQoYXJyYXkobWljcm8kc3BlY2hlYXRbMSxdLCBkaW0gPSBjKG5jb2wobWljcm8kc3BlY2hlYXQpLCBsZW5ndGgoVHdiNCkpKSkKICAgIGRpbW5hbWVzKG1pY3JvJHNwZWNoZWF0KSA8LSBzcGVjaGVhdG5hbWVzICAKICAgIG1pY3JvJGRlbnNpdCAgIDwtIHQoYXJyYXkobWljcm8kZGVuc2l0WzEsXSwgZGltID0gYyhuY29sKG1pY3JvJGRlbnNpdCksIGxlbmd0aChUd2I0KSkpKQogICAgZGltbmFtZXMobWljcm8kZGVuc2l0KSA8LSBkZW5zaXRuYW1lcyAgICAgIAogICAgbWljcm8kcGxhbnQgICAgPC0gdChhcnJheShtaWNybyRwbGFudFsxLF0sIGRpbSA9IGMobmNvbChtaWNybyRwbGFudCksIGxlbmd0aChUd2I0KSkpKQogICAgZGltbmFtZXMobWljcm8kcGxhbnQpIDwtIHBsYW50bmFtZXMgCiAgICAKICAgIG1pY3JvJHNoYWRtZXQgICAgICA8LSBtaWNybyRtZXRvdXQKICAgIG1pY3JvJHNoYWRzb2lsICAgICA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRodW1pZCAgICAgICAgPC0gbWljcm8kc29pbAogICAgbWljcm8kc2hhZGh1bWlkICAgIDwtIG1pY3JvJHNvaWwKICAgIG1pY3JvJHNvaWxwb3QgICAgICA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRzaGFkcG90ICAgICAgPC0gbWljcm8kc29pbAogICAgbWljcm8kc29pbG1vaXN0ICAgIDwtIG1pY3JvJHNvaWwKICAgIG1pY3JvJHNoYWRtb2lzdCAgICA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRzaGFkdGNvbmQgICAgPC0gbWljcm8kdGNvbmQKICAgIG1pY3JvJHNoYWRkZW5zaXQgICA8LSBtaWNybyRkZW5zaXQKICAgIG1pY3JvJHNoYWRzcGVjaGVhdCA8LSBtaWNybyRzcGVjaGVhdAogICAgbWljcm8kc2hhZHBsYW50ICAgIDwtIG1pY3JvJHBsYW50CiAgICBtaWNybyRSQUlORkFMTCAgICAgPC0gcmVwKDAsIGxlbmd0aChUd2I0KS8yNCkKICAgIG1pY3JvJG1pbnNoYWRlICAgICA8LSByZXAoMCwgbGVuZ3RoKFR3YjQpLzI0KQogICAgbWljcm8kbWF4c2hhZGUgICAgIDwtIHJlcCg5MCwgbGVuZ3RoKFR3YjQpLzI0KQogICAgbWljcm8kbnllYXJzICAgICAgIDwtIGNlaWxpbmcobGVuZ3RoKFR3YjQpLzI0LzM2NSkKICAgIAogICAgIyByZXBsYWNlIGZpcnN0IGxpbmUgb2YgbWljcm9jbGltYXRlIGlucHV0IHdpdGggYWlyIHRlbXBlcmF0dXJlIGFuZCBodW1pZGl0eSBhdCB3aGljaCB0byBjb21wdXRlIFR3CiAgICBtaWNybyRtZXRvdXRbMTpsZW5ndGgoVHdiNCksYygzLDQsMTQpXSA8LSBjKFRhMltzdGFydDplbmRdLCByZXAoVGEyWzFdLCBleHRyYSkpICMgc2V0IGFpciBhbmQgc2t5IHRlbXBlcmF0dXJlCiAgICBtaWNybyRtZXRvdXRbMTpsZW5ndGgoVHdiNCksYyg1LDYpXSAgICA8LSBjKFJIMltzdGFydDplbmRdLCByZXAoUkgyWzFdLCBleHRyYSkpICMgc2V0IHJlbGF0aXZlIGh1bWlkaXR5CiAgICAjIG1pY3JvJG1ldG91dFsxOmxlbmd0aChUd2IzKSxjKDcsOCldIDwtIDAuMDUgIyBzZXQgd2luZCBzcGVlZCB0byBsb3cgKHNlbnNpdGl2ZSB0byB0aGlzKQogICAgbWljcm8kc29pbFsxOmxlbmd0aChUd2I0KSwzXSA8LSBjKFRhMltzdGFydDplbmRdLCByZXAoVGEyWzFdLCBleHRyYSkpICMgc2V0IHN1cmZhY2Ugc29pbCB0ZW1wZXJhdHVyZSB0byBhaXIgdGVtcGVyYXR1cmUKICAgIG1pY3JvJG1ldG91dFsxOmxlbmd0aChUd2I0KSwgMl0gPC0gcmVwKHNlcSgwLCAyMyAqIDYwLCA2MCksIGxlbmd0aChUYTIpLzI0ICsgMSlbMTpsZW5ndGgoVHdiNCldCiAgICAjbWljcm8kbWV0b3V0WzE6bGVuZ3RoKFR3YjMpLCAxXSA8LSBzZXEoMCwgMjMgKiA2MCwgNjApWzE6bGVuZ3RoKFR3YjMpXQogICAgcHJlc2hyIDwtIGMoUDJbc3RhcnQ6ZW5kXSwgcmVwKFAyWzFdLCBleHRyYSkpKjEwMDAgICAgICAgICAgCiAgICAKICAgIG1pY3JvJG1ldG91dFsxOmxlbmd0aChUd2I0KSxjKDcsOCldIDwtIGMod3MyW3N0YXJ0OmVuZF0sIHJlcCh3czJbMV0sIGV4dHJhKSkgIyBzZXQgd2luZCBzcGVlZCAgICAKICAgIAogICAgIyBydW4gdGhlIGVjdG90aGVybSBtb2RlbCAKICAgIG1lc3NhZ2UocGFzdGUoJ3J1bm5pbmcgZWN0b3RoZXJtIHNpbXVsYXRpb24gZm9yIG1vbnRoICcsbW9udGgsJyBmb3IgJywgbGVuZ3RoKFR3YjQpLCcgc2l0ZXMgXG4nKSkKICAgIHB0bSA8LSBwcm9jLnRpbWUoKSAjIFN0YXJ0IHRpbWluZwogICAgZ2MoKQogICAgZWN0byA8LSBlY3RvdGhlcm0oV3dfZyA9IDguNywKICAgICAgICAgICAgICAgICAgICAgIGxpdmUgPSAwLAogICAgICAgICAgICAgICAgICAgICAgcGN0X3dldCA9IDg3LAogICAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSA0LCAjIGZyb2cKICAgICAgICAgICAgICAgICAgICAgIHByZXNociA9IHByZXNocikKICAgIG1lc3NhZ2UocGFzdGUwKCdydW50aW1lICcsIChwcm9jLnRpbWUoKSAtIHB0bSlbM10sICcgc2Vjb25kcycpKSAjIFN0b3AgdGhlIGNsb2NrCiAgICBnYygpCiAgICBlbnZpcm9uIDwtIGFzLmRhdGEuZnJhbWUoZWN0byRlbnZpcm9uKQogICAgbWFzYmFsIDwtIGFzLmRhdGEuZnJhbWUoZWN0byRtYXNiYWwpCiAgICBpZihrID09IDEpewogICAgICBUYi5lY3RvdGhlcm0gPC0gZW52aXJvbiRUQ1sxOihucm93KGVudmlyb24pIC0gZXh0cmEpXQogICAgICBFV0wuZWN0b3RoZXJtIDwtIG1hc2JhbCRIMk9DdXRfZ1sxOihucm93KG1hc2JhbCkgLSBleHRyYSldCiAgICB9ZWxzZXsKICAgICAgVGIuZWN0b3RoZXJtIDwtIGMoVGIuZWN0b3RoZXJtLCBlbnZpcm9uJFRDWzE6KG5yb3coZW52aXJvbikgLSBleHRyYSldKQogICAgICBFV0wuZWN0b3RoZXJtIDwtIGMoRVdMLmVjdG90aGVybSwgbWFzYmFsJEgyT0N1dF9nWzE6KG5yb3cobWFzYmFsKSAtIGV4dHJhKV0pCiAgICB9CiAgfQogIFRiMiA8LSBUYQogIFRiMlshaXMubmEoVGEpXSA8LSBUYi5lY3RvdGhlcm0KICBUYi5ncmlkIDwtIFRhLncKICBUYi5ncmlkIDwtIHNldFZhbHVlcyhUYi5ncmlkLCBUYjIpCiAgI3Bsb3QoVGIuZ3JpZCkKICAjbWFwKCd3b3JsZCcsIGFkZCA9IFRSVUUpCiAgCiAgRVdMMiA8LSBUYQogIEVXTDJbIWlzLm5hKFRhKV0gPC0gRVdMLmVjdG90aGVybQogIEVXTC5ncmlkIDwtIFRhLncKICBFV0wuZ3JpZCA8LSBzZXRWYWx1ZXMoRVdMLmdyaWQsIEVXTDIpCiAgI3Bsb3QoRVdMLmdyaWQpCiAgRVdMLmdyaWRbVGIuZ3JpZCA8PSAwXSA8LSBOQQogICNtYXAoJ3dvcmxkJywgYWRkID0gVFJVRSkKICAKICB3cml0ZVJhc3RlcihFV0wuZ3JpZCwgZmlsZSA9IHBhc3RlMCgnRVdMXycsbW9udGgsJ18yQy5uYycpLCBvdmVyd3JpdGU9VFJVRSkKfSAgCgojIyArNEMgIyMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgU2F0dXJhdGVkIHZhcG91ciBwcmVzc3VyZQp0bWF4X2Z1bGxfNEMgPC0gcmFzdGVyOjpicmljayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnVGVycmFDbGltYXRlNENfdG1heC5uYycpKSAjIDJtLCBkZWcgQwplc19rUGFfNEMgICAgPC0gdG1heF9mdWxsXzRDCnZhbHVlcyhlc19rUGFfNEMpIDwtIDAuNjExICogZXhwKDI1MDAwMDAgLyA0NjEuNSAqICggMSAvIDI3MyAtIDEgLyAodmFsdWVzKHRtYXhfZnVsbF80QykgKyAyNzMuMTUpKSkKCiMgQWN0dWFsIHZhcG91ciBwcmVzc3VyZQplYV9rUGEgICAgICA8LSByYXN0ZXI6OmJyaWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdUZXJyYUNsaW1hdGUxOTgxMjAxMF92YXAubmMnKSkKZWFfa1BhXzRDICAgPC0gZWFfa1BhCnZhbHVlcyhlYV9rUGFfNEMpIDwtIHZhbHVlcyhlYV9rUGFfNEMpICogMC44CgojIENhbGN1bGF0ZSBWUEQgKGtQYSkKdnBkX2Z1bGxfNEMgPC0gZWFfa1BhXzRDCnZhbHVlcyh2cGRfZnVsbF80QykgPC0gdmFsdWVzKGVzX2tQYV80QykgLSB2YWx1ZXMoZWFfa1BhXzRDKQoKVGJzICA8LSBjcm9wKHRtYXhfZnVsbF80QywgZXh0ZW50KGVsZXYpKQpFV0xzIDwtIFRicyAKCiMgUnVuIGVjdG90aGVybSBtb2RlbCBmb3IgZWFjaCBtb250aCBhbmQgc2F2ZSBvbiBsb2NhbCBkcml2ZSAoKzRDIHNjZW5hcmlvKQpmb3IobW9udGggaW4gMToxMil7CiAgVGEudyAgIDwtIGNyb3AodG1heF9mdWxsXzRDW1ttb250aF1dLCBleHRlbnQoZWxldikpCiAgZXNhdCAgIDwtIFZBUFBSUyhUYS53KQogIGUgICAgICA8LSBlc2F0IC0gY3JvcCh2cGRfZnVsbF80Q1tbbW9udGhdXSwgZXh0ZW50KGVsZXYpKSAqIDEwMDAKICBSSC53ICAgPC0gZSAvIGVzYXQgKiAxMDAKICBSSC53W1JILncgPCAwXSA8LSAwCiAgV2luZC53IDwtIGNyb3Aod3NfZnVsbFtbbW9udGhdXSwgZXh0ZW50KGVsZXYpKQogIFZzdGFyICA8LSAwLjQgKiBXaW5kLncgLyBsb2coKDEwMCAvIDAuMTUpICsgMSkgIyBmcmljdGlvbiB2ZWxvY2l0eQogIFdpbmQudyA8LSAyLjUgKiBWc3RhciAqIGxvZygoMSAvIDAuMTUpICsgMSkgIyBjb3JyZWN0IGZvciByZWZlcmVuY2UgaGVpZ2h0ICgxMCBtKSB0byBncm91bmQgbGV2ZWwgKDEgY20pIGFzc3VtaW5nIGxldmVsIGdyb3VuZAogICMgY29tcHV0ZSBhdG1vc3BoZXJpYyBwcmVzc3VyZSAoa1BhKQogIFAudyA8LSAxMDEzMjUgKiAoKDEgLSAoMC4wMDY1ICogZWxldiAvIDI4OCkpIF4gKDEgLyAwLjE5MDI4NCkpIC8gMTAwMAogIAogIFRhICA8LSBnZXRWYWx1ZXMoVGEudykKICBSSCAgPC0gZ2V0VmFsdWVzKFJILncpCiAgUCAgIDwtIGdldFZhbHVlcyhQLncpCiAgUGEgIDwtIGdldFZhbHVlcyhlKQogIHdzICA8LSBnZXRWYWx1ZXMoV2luZC53KQogIFBbIWlzLm5hKFRhKSAmIGlzLm5hKFApXSA8LSAxMDEuMzI1CiAgVGEyIDwtIFRhWyFpcy5uYShUYSldCiAgUkgyIDwtIFJIWyFpcy5uYShUYSldCiAgUDIgIDwtIFBbIWlzLm5hKFRhKV0KICB3czIgPC0gd3NbIWlzLm5hKFRhKV0KICBQYTIgPC0gUGFbIWlzLm5hKFRhKV0KICAKICBkaXYgPC0gMTAKICBUd2IgPC0gVGEyWzE6Zmxvb3IobGVuZ3RoKFRhMikgLyBkaXYpXQogIG1pY3JvX2Jhc2UgPC0gbWljcm9fZ2xvYmFsKCkKICAKICBmb3IoayBpbiAxOmRpdil7CiAgICBtaWNybyA8LSBtaWNyb19iYXNlCiAgICBpZihrID09IDEpewogICAgICBleHRyYSA8LSByb3VuZCgyNCAtIChsZW5ndGgoVHdiKSAvIDI0KSUlMSAqIDI0LCAwKQogICAgICBUd2I0ICA8LSBjKFR3YiwgcmVwKFRhMlsxXSwgZXh0cmEpKQogICAgICBzdGFydCA8LSAxCiAgICAgIGVuZCAgIDwtIGxlbmd0aChUd2IpCiAgICB9CiAgICBpZihrID4gMSAmIGsgPCBkaXYpewogICAgICBmYWN0ICA8LSAobGVuZ3RoKFR3YikgKiAoayAtIDEpICsgayAtIDEpCiAgICAgIFR3YjQgIDwtIFRhMltmYWN0OihmYWN0ICsgbGVuZ3RoKFR3YikpXQogICAgICBleHRyYSA8LSByb3VuZCgyNCAtIChsZW5ndGgoVHdiNCkgLyAyNCklJTEgKiAyNCwgMCkKICAgICAgVHdiNCAgPC0gYyhUd2I0LCByZXAoVGEyWzFdLCBleHRyYSkpCiAgICAgIHN0YXJ0IDwtIGZhY3QKICAgICAgZW5kICAgPC0gZmFjdCArIGxlbmd0aChUd2IpCiAgICB9ICAgICAgICAKICAgIGlmKGsgPT0gZGl2KXsKICAgICAgZmFjdCAgPC0gKGxlbmd0aChUd2IpICogKGsgLSAxKSArIGsgLSAxKQogICAgICBUd2I0ICA8LSBUYTJbZmFjdDpsZW5ndGgoVGEyKV0KICAgICAgZXh0cmEgPC0gcm91bmQoMjQgLSAobGVuZ3RoKFR3YjQpIC8gMjQpJSUxICogMjQsIDApCiAgICAgIFR3YjQgIDwtIGMoVHdiNCwgcmVwKFRhMlsxXSwgZXh0cmEpKQogICAgICBzdGFydCA8LSBmYWN0CiAgICAgIGVuZCAgIDwtIGxlbmd0aChUYTIpCiAgICB9IAogICAgCiAgICBzb2lsbmFtZXMgICAgIDwtIGRpbW5hbWVzKG1pY3JvJHNvaWwpCiAgICBtZXRvdXRuYW1lcyAgIDwtIGRpbW5hbWVzKG1pY3JvJG1ldG91dCkKICAgIHRjb25kbmFtZXMgICAgPC0gZGltbmFtZXMobWljcm8kdGNvbmQpCiAgICBzcGVjaGVhdG5hbWVzIDwtIGRpbW5hbWVzKG1pY3JvJHNwZWNoZWF0KQogICAgZGVuc2l0bmFtZXMgICA8LSBkaW1uYW1lcyhtaWNybyRkZW5zaXQpCiAgICBwbGFudG5hbWVzICAgIDwtIGRpbW5hbWVzKG1pY3JvJHBsYW50KQogICAgCiAgICBtaWNybyRtZXRvdXQgICA8LSB0KGFycmF5KG1pY3JvJG1ldG91dFsxLF0sIGRpbSA9IGMobmNvbChtaWNybyRtZXRvdXQpLCBsZW5ndGgoVHdiNCkpKSkKICAgIGRpbW5hbWVzKG1pY3JvJG1ldG91dCkgPC0gbWV0b3V0bmFtZXMKICAgIG1pY3JvJHNvaWwgICAgIDwtIHQoYXJyYXkobWljcm8kc29pbFsxLF0sIGRpbSA9IGMobmNvbChtaWNybyRzb2lsKSwgbGVuZ3RoKFR3YjQpKSkpCiAgICBkaW1uYW1lcyhtaWNybyRzb2lsKSA8LSBzb2lsbmFtZXMKICAgIG1pY3JvJHRjb25kICAgIDwtIHQoYXJyYXkobWljcm8kdGNvbmRbMSxdLCBkaW0gPSBjKG5jb2wobWljcm8kdGNvbmQpLCBsZW5ndGgoVHdiNCkpKSkKICAgIGRpbW5hbWVzKG1pY3JvJHRjb25kKSA8LSB0Y29uZG5hbWVzCiAgICBtaWNybyRzcGVjaGVhdCA8LSB0KGFycmF5KG1pY3JvJHNwZWNoZWF0WzEsXSwgZGltID0gYyhuY29sKG1pY3JvJHNwZWNoZWF0KSwgbGVuZ3RoKFR3YjQpKSkpCiAgICBkaW1uYW1lcyhtaWNybyRzcGVjaGVhdCkgPC0gc3BlY2hlYXRuYW1lcyAgCiAgICBtaWNybyRkZW5zaXQgICA8LSB0KGFycmF5KG1pY3JvJGRlbnNpdFsxLF0sIGRpbSA9IGMobmNvbChtaWNybyRkZW5zaXQpLCBsZW5ndGgoVHdiNCkpKSkKICAgIGRpbW5hbWVzKG1pY3JvJGRlbnNpdCkgPC0gZGVuc2l0bmFtZXMgICAgICAKICAgIG1pY3JvJHBsYW50ICAgIDwtIHQoYXJyYXkobWljcm8kcGxhbnRbMSxdLCBkaW0gPSBjKG5jb2wobWljcm8kcGxhbnQpLCBsZW5ndGgoVHdiNCkpKSkKICAgIGRpbW5hbWVzKG1pY3JvJHBsYW50KSA8LSBwbGFudG5hbWVzIAogICAgCiAgICBtaWNybyRzaGFkbWV0ICAgICAgPC0gbWljcm8kbWV0b3V0CiAgICBtaWNybyRzaGFkc29pbCAgICAgPC0gbWljcm8kc29pbAogICAgbWljcm8kaHVtaWQgICAgICAgIDwtIG1pY3JvJHNvaWwKICAgIG1pY3JvJHNoYWRodW1pZCAgICA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRzb2lscG90ICAgICAgPC0gbWljcm8kc29pbAogICAgbWljcm8kc2hhZHBvdCAgICAgIDwtIG1pY3JvJHNvaWwKICAgIG1pY3JvJHNvaWxtb2lzdCAgICA8LSBtaWNybyRzb2lsCiAgICBtaWNybyRzaGFkbW9pc3QgICAgPC0gbWljcm8kc29pbAogICAgbWljcm8kc2hhZHRjb25kICAgIDwtIG1pY3JvJHRjb25kCiAgICBtaWNybyRzaGFkZGVuc2l0ICAgPC0gbWljcm8kZGVuc2l0CiAgICBtaWNybyRzaGFkc3BlY2hlYXQgPC0gbWljcm8kc3BlY2hlYXQKICAgIG1pY3JvJHNoYWRwbGFudCAgICA8LSBtaWNybyRwbGFudAogICAgbWljcm8kUkFJTkZBTEwgICAgIDwtIHJlcCgwLCBsZW5ndGgoVHdiNCkvMjQpCiAgICBtaWNybyRtaW5zaGFkZSAgICAgPC0gcmVwKDAsIGxlbmd0aChUd2I0KS8yNCkKICAgIG1pY3JvJG1heHNoYWRlICAgICA8LSByZXAoOTAsIGxlbmd0aChUd2I0KS8yNCkKICAgIG1pY3JvJG55ZWFycyAgICAgICA8LSBjZWlsaW5nKGxlbmd0aChUd2I0KS8yNC8zNjUpCiAgICAKICAgICMgcmVwbGFjZSBmaXJzdCBsaW5lIG9mIG1pY3JvY2xpbWF0ZSBpbnB1dCB3aXRoIGFpciB0ZW1wZXJhdHVyZSBhbmQgaHVtaWRpdHkgYXQgd2hpY2ggdG8gY29tcHV0ZSBUdwogICAgbWljcm8kbWV0b3V0WzE6bGVuZ3RoKFR3YjQpLGMoMyw0LDE0KV0gPC0gYyhUYTJbc3RhcnQ6ZW5kXSwgcmVwKFRhMlsxXSwgZXh0cmEpKSAjIHNldCBhaXIgYW5kIHNreSB0ZW1wZXJhdHVyZQogICAgbWljcm8kbWV0b3V0WzE6bGVuZ3RoKFR3YjQpLGMoNSw2KV0gICAgPC0gYyhSSDJbc3RhcnQ6ZW5kXSwgcmVwKFJIMlsxXSwgZXh0cmEpKSAjIHNldCByZWxhdGl2ZSBodW1pZGl0eQogICAgIyBtaWNybyRtZXRvdXRbMTpsZW5ndGgoVHdiMyksYyg3LDgpXSA8LSAwLjA1ICMgc2V0IHdpbmQgc3BlZWQgdG8gbG93IChzZW5zaXRpdmUgdG8gdGhpcykKICAgIG1pY3JvJHNvaWxbMTpsZW5ndGgoVHdiNCksM10gPC0gYyhUYTJbc3RhcnQ6ZW5kXSwgcmVwKFRhMlsxXSwgZXh0cmEpKSAjIHNldCBzdXJmYWNlIHNvaWwgdGVtcGVyYXR1cmUgdG8gYWlyIHRlbXBlcmF0dXJlCiAgICBtaWNybyRtZXRvdXRbMTpsZW5ndGgoVHdiNCksIDJdIDwtIHJlcChzZXEoMCwgMjMgKiA2MCwgNjApLCBsZW5ndGgoVGEyKS8yNCArIDEpWzE6bGVuZ3RoKFR3YjQpXQogICAgI21pY3JvJG1ldG91dFsxOmxlbmd0aChUd2IzKSwgMV0gPC0gc2VxKDAsIDIzICogNjAsIDYwKVsxOmxlbmd0aChUd2IzKV0KICAgIHByZXNociA8LSBjKFAyW3N0YXJ0OmVuZF0sIHJlcChQMlsxXSwgZXh0cmEpKSoxMDAwICAgICAgICAgIAogICAgCiAgICBtaWNybyRtZXRvdXRbMTpsZW5ndGgoVHdiNCksYyg3LDgpXSA8LSBjKHdzMltzdGFydDplbmRdLCByZXAod3MyWzFdLCBleHRyYSkpICMgc2V0IHdpbmQgc3BlZWQgICAgCiAgICAKICAgICMgcnVuIHRoZSBlY3RvdGhlcm0gbW9kZWwgCiAgICBtZXNzYWdlKHBhc3RlKCdydW5uaW5nIGVjdG90aGVybSBzaW11bGF0aW9uIGZvciBtb250aCAnLG1vbnRoLCcgZm9yICcsIGxlbmd0aChUd2I0KSwnIHNpdGVzIFxuJykpCiAgICBwdG0gPC0gcHJvYy50aW1lKCkgIyBTdGFydCB0aW1pbmcKICAgIGdjKCkKICAgIGVjdG8gPC0gZWN0b3RoZXJtKFd3X2cgPSA4LjcsCiAgICAgICAgICAgICAgICAgICAgICBsaXZlID0gMCwKICAgICAgICAgICAgICAgICAgICAgIHBjdF93ZXQgPSA4NywKICAgICAgICAgICAgICAgICAgICAgIHNoYXBlID0gNCwgIyBmcm9nCiAgICAgICAgICAgICAgICAgICAgICBwcmVzaHIgPSBwcmVzaHIpCiAgICBtZXNzYWdlKHBhc3RlMCgncnVudGltZSAnLCAocHJvYy50aW1lKCkgLSBwdG0pWzNdLCAnIHNlY29uZHMnKSkgIyBTdG9wIHRoZSBjbG9jawogICAgZ2MoKQogICAgZW52aXJvbiA8LSBhcy5kYXRhLmZyYW1lKGVjdG8kZW52aXJvbikKICAgIG1hc2JhbCA8LSBhcy5kYXRhLmZyYW1lKGVjdG8kbWFzYmFsKQogICAgaWYoayA9PSAxKXsKICAgICAgVGIuZWN0b3RoZXJtIDwtIGVudmlyb24kVENbMToobnJvdyhlbnZpcm9uKSAtIGV4dHJhKV0KICAgICAgRVdMLmVjdG90aGVybSA8LSBtYXNiYWwkSDJPQ3V0X2dbMToobnJvdyhtYXNiYWwpIC0gZXh0cmEpXQogICAgfWVsc2V7CiAgICAgIFRiLmVjdG90aGVybSA8LSBjKFRiLmVjdG90aGVybSwgZW52aXJvbiRUQ1sxOihucm93KGVudmlyb24pIC0gZXh0cmEpXSkKICAgICAgRVdMLmVjdG90aGVybSA8LSBjKEVXTC5lY3RvdGhlcm0sIG1hc2JhbCRIMk9DdXRfZ1sxOihucm93KG1hc2JhbCkgLSBleHRyYSldKQogICAgfQogIH0KICBUYjIgPC0gVGEKICBUYjJbIWlzLm5hKFRhKV0gPC0gVGIuZWN0b3RoZXJtCiAgVGIuZ3JpZCA8LSBUYS53CiAgVGIuZ3JpZCA8LSBzZXRWYWx1ZXMoVGIuZ3JpZCwgVGIyKQogICNwbG90KFRiLmdyaWQpCiAgI21hcCgnd29ybGQnLCBhZGQgPSBUUlVFKQogIAogIEVXTDIgPC0gVGEKICBFV0wyWyFpcy5uYShUYSldIDwtIEVXTC5lY3RvdGhlcm0KICBFV0wuZ3JpZCA8LSBUYS53CiAgRVdMLmdyaWQgPC0gc2V0VmFsdWVzKEVXTC5ncmlkLCBFV0wyKQogICNwbG90KEVXTC5ncmlkKQogIEVXTC5ncmlkW1RiLmdyaWQgPD0gMF0gPC0gTkEKICAjbWFwKCd3b3JsZCcsIGFkZCA9IFRSVUUpCiAgCiAgd3JpdGVSYXN0ZXIoRVdMLmdyaWQsIGZpbGUgPSBwYXN0ZTAoJ0VXTF8nLG1vbnRoLCdfNEMubmMnKSwgb3ZlcndyaXRlPVRSVUUpCn0gIApgYGAKCkNyZWF0ZSBwbG90cyBmb3IgbWFpbiB0ZXh0IGZpZ3VyZSAzLgoKYGBge3IgRmlnIDMsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NywgZmlnLnNob3c9J2hpZGUnfQojIEltcG9ydCB0aGUgZG93bmxvYWRlZCBmaWxlcwpFV0xfamFuIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfMS5uYycpKSwgYW51cmFuX3NyKQpFV0xfZmViIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfMi5uYycpKSwgYW51cmFuX3NyKQpFV0xfbWFyIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfMy5uYycpKSwgYW51cmFuX3NyKQpFV0xfYXByIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfNC5uYycpKSwgYW51cmFuX3NyKQpFV0xfbWF5IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfNS5uYycpKSwgYW51cmFuX3NyKQpFV0xfanVuIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfNi5uYycpKSwgYW51cmFuX3NyKQpFV0xfanVsIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfNy5uYycpKSwgYW51cmFuX3NyKQpFV0xfYXVnIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfOC5uYycpKSwgYW51cmFuX3NyKQpFV0xfc2VwIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfOS5uYycpKSwgYW51cmFuX3NyKQpFV0xfb2N0IDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfMTAubmMnKSksIGFudXJhbl9zcikKRVdMX25vdiA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzExLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9kZWMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF8xMi5uYycpKSwgYW51cmFuX3NyKQoKRVdMX2phbl8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzFfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX2ZlYl8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzJfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX21hcl8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzNfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX2Fwcl8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzRfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX21heV8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzVfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX2p1bl8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzZfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX2p1bF8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzdfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX2F1Z18yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzhfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX3NlcF8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzlfMkMubmMnKSksIGFudXJhbl9zcikKRVdMX29jdF8yQyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzEwXzJDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9ub3ZfMkMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF8xMV8yQy5uYycpKSwgYW51cmFuX3NyKQpFV0xfZGVjXzJDIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfMTJfMkMubmMnKSksIGFudXJhbl9zcikKCkVXTF9qYW5fNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF8xXzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9mZWJfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF8yXzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9tYXJfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF8zXzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9hcHJfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF80XzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9tYXlfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF81XzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9qdW5fNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF82XzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9qdWxfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF83XzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9hdWdfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF84XzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9zZXBfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF85XzRDLm5jJykpLCBhbnVyYW5fc3IpCkVXTF9vY3RfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soZmlsZS5wYXRoKHNwYXRpYWxfcGF0aCwgJ0VXTF8xMF80Qy5uYycpKSwgYW51cmFuX3NyKQpFV0xfbm92XzRDIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZpbGUucGF0aChzcGF0aWFsX3BhdGgsICdFV0xfMTFfNEMubmMnKSksIGFudXJhbl9zcikKRVdMX2RlY180QyA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhmaWxlLnBhdGgoc3BhdGlhbF9wYXRoLCAnRVdMXzEyXzRDLm5jJykpLCBhbnVyYW5fc3IpCgojIENvbWJpbmUgYWxsCkVXTF9hbGwgPC0gcmFzdGVyOjpzdGFjayhFV0xfamFuLCBFV0xfZmViLCBFV0xfbWFyLCBFV0xfYXByLCBFV0xfbWF5LCBFV0xfanVuLCAKICAgICAgICAgICAgICAgICAgICAgICAgIEVXTF9qdWwsIEVXTF9hdWcsIEVXTF9zZXAsIEVXTF9vY3QsIEVXTF9ub3YsIEVXTF9kZWMpCgpFV0xfYWxsXzJDIDwtIHJhc3Rlcjo6c3RhY2soRVdMX2phbl8yQywgRVdMX2ZlYl8yQywgRVdMX21hcl8yQywgRVdMX2Fwcl8yQywgRVdMX21heV8yQywgRVdMX2p1bl8yQywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFV0xfanVsXzJDLCBFV0xfYXVnXzJDLCBFV0xfc2VwXzJDLCBFV0xfb2N0XzJDLCBFV0xfbm92XzJDLCBFV0xfZGVjXzJDKQoKRVdMX2FsbF80QyA8LSByYXN0ZXI6OnN0YWNrKEVXTF9qYW5fNEMsIEVXTF9mZWJfNEMsIEVXTF9tYXJfNEMsIEVXTF9hcHJfNEMsIEVXTF9tYXlfNEMsIEVXTF9qdW5fNEMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRVdMX2p1bF80QywgRVdMX2F1Z180QywgRVdMX3NlcF80QywgRVdMX29jdF80QywgRVdMX25vdl80QywgRVdMX2RlY180QykKCkVXTF9hbGxfbWVhbiAgICA8LSByYXN0ZXI6OmNhbGMoRVdMX2FsbCwgZnVuID0gbWVhbiwgbmEucm0gPSBUUlVFKQpFV0xfYWxsX21lYW5fMkMgPC0gcmFzdGVyOjpjYWxjKEVXTF9hbGxfMkMsIGZ1biA9IG1lYW4sIG5hLnJtID0gVFJVRSkKRVdMX2FsbF9tZWFuXzRDIDwtIHJhc3Rlcjo6Y2FsYyhFV0xfYWxsXzRDLCBmdW4gPSBtZWFuLCBuYS5ybSA9IFRSVUUpCgpFV0xfZGlmZl8yQyA8LSByYXN0ZXI6Om92ZXJsYXkoeCA9IEVXTF9hbGxfbWVhbiwgeSA9IEVXTF9hbGxfbWVhbl8yQywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuID0gZnVuY3Rpb24oeCwgeSkge3JldHVybih5IC0geCl9KSAKCkVXTF9kaWZmXzRDIDwtIHJhc3Rlcjo6b3ZlcmxheSh4ID0gRVdMX2FsbF9tZWFuLCB5ID0gRVdMX2FsbF9tZWFuXzRDLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW4gPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuKHkgLSB4KX0pIAoKRVdMX3Jpc2tfcm9iICAgIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKEVXTF9hbGxfbWVhbiwgYW51cmFuX3NyLCBhcXVhdGljX3NyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJib3JlYWxfc3IsIGZvc3NvcmlhbF9zciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VuZF9zciwgc2VtaV9hcV9zciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbV9zciksIGNycyA9IHJvYl9wcm9qKQpFV0xfcmlza19yb2JfMkMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soRVdMX2RpZmZfMkMsIGFudXJhbl9zciksIGNycyA9IHJvYl9wcm9qKQpFV0xfcmlza19yb2JfNEMgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soRVdMX2RpZmZfNEMsIGFudXJhbl9zciksIGNycyA9IHJvYl9wcm9qKQoKRVdMX3NwX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKEVXTF9yaXNrX3JvYikpICU+JSAKICByZW5hbWUoRVdMICAgICAgID0gbGF5ZXIuMSwgCiAgICAgICAgIHNwZWNpZXNfbiA9IGxheWVyLjIsCiAgICAgICAgIGFxdWFfc3AgPSBsYXllci4zLAogICAgICAgICBhcmJvX3NwID0gbGF5ZXIuNCwKICAgICAgICAgZm9zc19zcCA9IGxheWVyLjUsCiAgICAgICAgIGdyb25fc3AgPSBsYXllci42LAogICAgICAgICBzZW1pX3NwID0gbGF5ZXIuNywKICAgICAgICAgc3RybV9zcCA9IGxheWVyLjgpICU+JQogIGRyb3BfbmEoc3BlY2llc19uKQoKRVdMX3NwXzJDX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKEVXTF9yaXNrX3JvYl8yQykpICU+JSAKICByZW5hbWUoRVdMX2RpZmYgID0gbGF5ZXIuMSwgCiAgICAgICAgIHNwZWNpZXNfbiA9IGxheWVyLjIpICU+JQogIGRyb3BfbmEoc3BlY2llc19uKQoKRVdMX3NwXzRDX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKEVXTF9yaXNrX3JvYl80QykpICU+JSAKICByZW5hbWUoRVdMX2RpZmYgID0gbGF5ZXIuMSwgCiAgICAgICAgIHNwZWNpZXNfbiA9IGxheWVyLjIpICU+JQogIGRyb3BfbmEoc3BlY2llc19uKQoKIyBGaWcuIDNhCkVXTF9jdXJfcGxvdCA8LSBFV0xfc3BfZGYgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBFV0wpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJZbEduQnUiLCByZXYgPSBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gZXhwcmVzc2lvbigiRVdMIn4oImcifkhbMl0qT35oXnsiLTEifSkpKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcndpZHRoID0gMjAsIGJhcmhlaWdodCA9IDAuMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCiMgRmlnLiAzYiAtIFNwZWNpZXMgcmljaG5lc3MgYW5kIEVXTApFV0xfc3BfcGxvdCA8LSBFV0xfc3BfZGYgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRVdMLCB5ID0gc3BlY2llc19uKSkgKwogIGdlb21fcG9pbnQoY29sb3VyID0gImdyZXkiKSArCiAgeGxhYihleHByZXNzaW9uKCJFV0wifigiZyJ+SFsyXSpPfmheeyItMSJ9KSkpICsKICB5bGFiKCJTcGVjaWVzIHJpY2huZXNzIikgKwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAzLCAwLjUpLCBleHBhbmQgPSBjKDAsIDApKSArIAogIG15dGhlbWUoKQoKIyBGaWcuIDNjICsyQwpFV0xfMkNfcGxvdCA8LSBFV0xfc3BfMkNfZGYgJT4lCiAgZHBseXI6Om11dGF0ZShFV0xfZGlmZl9jYXQgPSBjYXNlX3doZW4oCiAgICBFV0xfZGlmZiA9PSAwIH4gJzAnLAogICAgRVdMX2RpZmYgPiAwICYgRVdMX2RpZmYgPD0xIH4gJzwxJywKICAgIEVXTF9kaWZmID49IDEgJiBFV0xfZGlmZiA8IDEuNSB+ICc+MSB0byAxLjUnLAogICAgRVdMX2RpZmYgPj0gMS41ICYgRVdMX2RpZmYgPCAyIH4gJz4xLjUgdG8gMicsCiAgICBFV0xfZGlmZiA+PSAyICYgRVdMX2RpZmYgPCAyLjUgfiAnPjIgdG8gMi41JywKICAgIEVXTF9kaWZmID49IDIuNSAmIEVXTF9kaWZmIDwgMyB+ICc+Mi41IHRvIDMnLAogICAgRVdMX2RpZmYgPiAzIH4gJz4zJyksCiAgICBFV0xfZGlmZiA9IG5hX2lmKEVXTF9kaWZmLCAwKSwKICAgIEVXTF9kaWZmY2F0ID0gZmFjdG9yKEVXTF9kaWZmX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc+MycsICc8Mi41IHRvIDMnLCc+MiB0byAyLjUnLCAnMS41IHRvIDInLCAnPjEgdG8gMS41JywgJzwxJykpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IEVXTF9kaWZmX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjRTJFNkJEIiwgIiNFN0NCNDciLCAiI0VBQUIyOCIsICIjRTc4QTM4IiwgIiNERjY3NTMiLCAiI0QzM0Y2QSIpLCBuYS50cmFuc2xhdGUgPSBGLCBuYW1lID0gZXhwcmVzc2lvbihEZWx0YSoiRVdMIn4oImcifkhbMl0qT35oXnsiLTEifSkpKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcndpZHRoID0gMjAsIGJhcmhlaWdodCA9IDAuMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCiMgRmlnLiAzZCArNEMKRVdMXzRDX3Bsb3QgPC0gRVdMX3NwXzRDX2RmICU+JQogIGRwbHlyOjptdXRhdGUoRVdMX2RpZmZfY2F0ID0gY2FzZV93aGVuKAogICAgRVdMX2RpZmYgPT0gMCB+ICcwJywKICAgIEVXTF9kaWZmID4gMCAmIEVXTF9kaWZmIDw9MSB+ICc8MScsCiAgICBFV0xfZGlmZiA+PSAxICYgRVdMX2RpZmYgPCAxLjUgfiAnPjEgdG8gMS41JywKICAgIEVXTF9kaWZmID49IDEuNSAmIEVXTF9kaWZmIDwgMiB+ICc+MS41IHRvIDInLAogICAgRVdMX2RpZmYgPj0gMiAmIEVXTF9kaWZmIDwgMi41IH4gJz4yIHRvIDIuNScsCiAgICBFV0xfZGlmZiA+PSAyLjUgJiBFV0xfZGlmZiA8IDMgfiAnPjIuNSB0byAzJywKICAgIEVXTF9kaWZmID4gMyB+ICc+MycpLAogICAgRVdMX2RpZmYgPSBuYV9pZihFV0xfZGlmZiwgMCksCiAgICBFV0xfZGlmZmNhdCA9IGZhY3RvcihFV0xfZGlmZl9jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnPjMnLCAnPDIuNSB0byAzJywnPjIgdG8gMi41JywgJzEuNSB0byAyJywgJz4xIHRvIDEuNScsICc8MScpKSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBFV0xfZGlmZl9jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0UyRTZCRCIsICIjRTdDQjQ3IiwgIiNFQUFCMjgiLCAiI0U3OEEzOCIsICIjREY2NzUzIiwgIiNEMzNGNkEiKSwgbmEudHJhbnNsYXRlID0gRiwgbmFtZSA9IGV4cHJlc3Npb24oRGVsdGEqIkVXTCJ+KCJnIn5IWzJdKk9+aF57Ii0xIn0pKSkgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjFlNSwgODVlNSksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTVlNiwgMTZlNiksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJ3aWR0aCA9IDIwLCBiYXJoZWlnaHQgPSAwLjIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsLnBvc2l0aW9uID0gImJvdHRvbSIpKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgpjb3dwbG90OjpwbG90X2dyaWQoRVdMX2N1cl9wbG90LAogICAgICAgICAgICAgICAgICAgRVdMX3NwX3Bsb3QsCiAgICAgICAgICAgICAgICAgICBFV0xfMkNfcGxvdCwKICAgICAgICAgICAgICAgICAgIEVXTF80Q19wbG90LAogICAgICAgICAgICAgICAgICAgbmNvbCA9IDIsCiAgICAgICAgICAgICAgICAgICBhbGlnbiA9ICJoIiwgYXhpcyA9ICJidCIsIGxhYmVscyA9IGMoJ2EnLCAnYicsICdjJywgJ2QnKSkKYGBgCgojIyBGaWd1cmUgNCAtIEFjdGl2aXR5IHJpc2sgey19CgpDcmVhdGUgcGxvdHMgZm9yIG1haW4gdGV4dCBmaWd1cmUgNC4KCmBgYCB7ciBGaWcgNCwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD04LCBmaWcuc2hvdz0naGlkZSd9CnNoYWRfcGxvdCA8LSBzaGFkX21vZGVsICU+JQogIGdncGxvdChhZXMoeCA9IGRheSwgeSA9IGNvbmRpdGlvbiwgZmlsbCA9IGhvdXJzKSkgKyAKICBnZW9tX3RpbGUoKSArCiAgdmlyaWRpczo6c2NhbGVfZmlsbF92aXJpZGlzKG9wdGlvbiA9ICJtYWdtYSIpICsKICAjc2NhbGVfZmlsbF9jb250aW51b3VzX2RpdmVyZ2luZyhwYWxldHRlID0gIkJsdWUtUmVkIDMiLCBtaWQgPSAxMiwgcmV2ID0gVFJVRSkgKwogIHlsYWIoTlVMTCkgKyB4bGFiKCJEYXkgb2YgdGhlIHllYXIiKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMzY1LCA1MCksIGV4cGFuZCA9IGMoMCwgMCkpICsgCiAgbXl0aGVtZSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJoZWlnaHQgPSAwLjUsIGJhcndpZHRoID0gNSwgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpIAoKdHJlZV9wbG90IDwtIHRyZWVfbW9kZWwgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGF5LCB5ID0gY29uZGl0aW9uLCBmaWxsID0gaG91cnMpKSArIAogIGdlb21fdGlsZSgpICsKICB2aXJpZGlzOjpzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gIm1hZ21hIikgKwogICNzY2FsZV9maWxsX2NvbnRpbnVvdXNfZGl2ZXJnaW5nKHBhbGV0dGUgPSAiQmx1ZS1SZWQgMyIsIG1pZCA9IDEyLCByZXYgPSBUUlVFKSArCiAgeWxhYihOVUxMKSArIHhsYWIoIkRheSBvZiB0aGUgeWVhciIpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAzNjUsIDUwKSwgZXhwYW5kID0gYygwLCAwKSkgKyAKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcmhlaWdodCA9IDAuNSwgYmFyd2lkdGggPSA1LCBsYWJlbC5wb3NpdGlvbiA9ICJib3R0b20iKSkgCgpidXJyX3Bsb3QgPC0gYnVycl9tb2RlbCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXksIHkgPSBjb25kaXRpb24sIGZpbGwgPSBob3VycykpICsgCiAgZ2VvbV90aWxlKCkgKwogIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcyhvcHRpb24gPSAibWFnbWEiKSArCiAgI3NjYWxlX2ZpbGxfY29udGludW91c19kaXZlcmdpbmcocGFsZXR0ZSA9ICJCbHVlLVJlZCAzIiwgbWlkID0gMTIsIHJldiA9IFRSVUUpICsKICB5bGFiKE5VTEwpICsgeGxhYigiRGF5IG9mIHRoZSB5ZWFyIikgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMzY1LCA1MCksIGV4cGFuZCA9IGMoMCwgMCkpICsgCiAgbXl0aGVtZSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJoZWlnaHQgPSAwLjUsIGJhcndpZHRoID0gNSwgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpIAoKcHJvd18yIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZCgKICBzaGFkX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSJub25lIiksIAogIHRyZWVfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9Im5vbmUiKSwgCiAgYnVycl9wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0ibm9uZSIpLAogIG5jb2wgPSAxLCBsYWJlbHMgPSBjKCdhJywgJ2MnLCAnZScpLAogIGFsaWduID0gJ3YnLCBheGlzID0gJ2wnKQoKbGVnZW5kX2JfMiA8LSBjb3dwbG90OjpnZXRfbGVnZW5kKGJ1cnJfcGxvdCArIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpKQp0b3BfZ3JhcGggIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChwcm93XzIsIGxlZ2VuZF9iXzIsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMSwgLjEpKQoKIyBSZWxhdGl2ZSBjaGFuZ2UKc2hhZF9kaWZmX21vZGVsIDwtIHNoYWRfY3Vycl93ZXRfZGYgJT4lCiAgbWVyZ2Uoc2hhZF9jdXJyX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2Uoc2hhZF93YXJtX3dldF9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2Uoc2hhZF93YXJtX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgZHBseXI6Om11dGF0ZShjdXJyX2RyeV9kaWZmID0gY3Vycl9kcnkgLSBjdXJyX3dldCwKICAgICAgICAgICAgICAgIHdhcm1fd2V0X2RpZmYgPSB3YXJtX3dldCAtIGN1cnJfd2V0LAogICAgICAgICAgICAgICAgd2FybV9kcnlfZGlmZiA9IHdhcm1fZHJ5IC0gY3Vycl93ZXQpICU+JQogIHBpdm90X2xvbmdlcighZGF5LCBuYW1lc190byA9ICJjb25kaXRpb24iLCB2YWx1ZXNfdG8gPSAiaG91cnMiKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbmRpdGlvbiA9PSBjKCJjdXJyX2RyeV9kaWZmIiwgIndhcm1fd2V0X2RpZmYiLCAid2FybV9kcnlfZGlmZiIpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGNvbmRpdGlvbiA9IGZhY3Rvcihjb25kaXRpb24sIGxldmVscyA9IGMoIndhcm1fZHJ5X2RpZmYiLCAid2FybV93ZXRfZGlmZiIsICJjdXJyX2RyeV9kaWZmIikpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXksIHkgPSBjb25kaXRpb24sIGZpbGwgPSBob3VycykpICsgCiAgZ2VvbV90aWxlKCkgKwogIHNjYWxlX2ZpbGxfY29udGludW91c19kaXZlcmdpbmcocGFsZXR0ZSA9ICJCbHVlLVJlZCAzIiwgbWlkID0gMCwgcmV2ID0gVFJVRSwgbGltaXRzID0gYygtMTUsIDE1KSkgKwogIHlsYWIoTlVMTCkgKyB4bGFiKCJEYXkgb2YgdGhlIHllYXIiKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMzY1LCA1MCksIGV4cGFuZCA9IGMoMCwgMCkpICsgCiAgbXl0aGVtZSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJoZWlnaHQgPSAwLjUsIGJhcndpZHRoID0gNSwgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpIAoKdHJlZV9kaWZmX21vZGVsIDwtIHRyZWVfY3Vycl93ZXRfZGYgJT4lCiAgbWVyZ2UodHJlZV9jdXJyX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2UodHJlZV93YXJtX3dldF9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2UodHJlZV93YXJtX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgZHBseXI6Om11dGF0ZShjdXJyX2RyeV9kaWZmID0gY3Vycl9kcnkgLSBjdXJyX3dldCwKICAgICAgICAgICAgICAgIHdhcm1fd2V0X2RpZmYgPSB3YXJtX3dldCAtIGN1cnJfd2V0LAogICAgICAgICAgICAgICAgd2FybV9kcnlfZGlmZiA9IHdhcm1fZHJ5IC0gY3Vycl93ZXQpICU+JQogIHBpdm90X2xvbmdlcighZGF5LCBuYW1lc190byA9ICJjb25kaXRpb24iLCB2YWx1ZXNfdG8gPSAiaG91cnMiKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbmRpdGlvbiA9PSBjKCJjdXJyX2RyeV9kaWZmIiwgIndhcm1fd2V0X2RpZmYiLCAid2FybV9kcnlfZGlmZiIpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGNvbmRpdGlvbiA9IGZhY3Rvcihjb25kaXRpb24sIGxldmVscyA9IGMoIndhcm1fZHJ5X2RpZmYiLCAid2FybV93ZXRfZGlmZiIsICJjdXJyX2RyeV9kaWZmIikpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXksIHkgPSBjb25kaXRpb24sIGZpbGwgPSBob3VycykpICsgCiAgZ2VvbV90aWxlKCkgKwogIHNjYWxlX2ZpbGxfY29udGludW91c19kaXZlcmdpbmcocGFsZXR0ZSA9ICJCbHVlLVJlZCAzIiwgbWlkID0gMCwgcmV2ID0gVFJVRSwgbGltaXRzID0gYygtMTUsIDE1KSkgKwogIHlsYWIoTlVMTCkgKyB4bGFiKCJEYXkgb2YgdGhlIHllYXIiKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMzY1LCA1MCksIGV4cGFuZCA9IGMoMCwgMCkpICsgCiAgbXl0aGVtZSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJoZWlnaHQgPSAwLjUsIGJhcndpZHRoID0gNSwgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpIAoKYnVycl9kaWZmX21vZGVsIDwtIGJ1cnJfY3Vycl93ZXRfZGYgJT4lCiAgbWVyZ2UoYnVycl9jdXJyX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2UoYnVycl93YXJtX3dldF9kZiwgYnkgPSAiZGF5IikgJT4lCiAgbWVyZ2UoYnVycl93YXJtX2RyeV9kZiwgYnkgPSAiZGF5IikgJT4lCiAgZHBseXI6Om11dGF0ZShjdXJyX2RyeV9kaWZmID0gY3Vycl9kcnkgLSBjdXJyX3dldCwKICAgICAgICAgICAgICAgIHdhcm1fd2V0X2RpZmYgPSB3YXJtX3dldCAtIGN1cnJfd2V0LAogICAgICAgICAgICAgICAgd2FybV9kcnlfZGlmZiA9IHdhcm1fZHJ5IC0gY3Vycl93ZXQpICU+JQogIHBpdm90X2xvbmdlcighZGF5LCBuYW1lc190byA9ICJjb25kaXRpb24iLCB2YWx1ZXNfdG8gPSAiaG91cnMiKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNvbmRpdGlvbiA9PSBjKCJjdXJyX2RyeV9kaWZmIiwgIndhcm1fd2V0X2RpZmYiLCAid2FybV9kcnlfZGlmZiIpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGNvbmRpdGlvbiA9IGZhY3Rvcihjb25kaXRpb24sIGxldmVscyA9IGMoIndhcm1fZHJ5X2RpZmYiLCAid2FybV93ZXRfZGlmZiIsICJjdXJyX2RyeV9kaWZmIikpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXksIHkgPSBjb25kaXRpb24sIGZpbGwgPSBob3VycykpICsgCiAgZ2VvbV90aWxlKCkgKwogIHNjYWxlX2ZpbGxfY29udGludW91c19kaXZlcmdpbmcocGFsZXR0ZSA9ICJCbHVlLVJlZCAzIiwgbWlkID0gMCwgcmV2ID0gVFJVRSwgbGltaXRzID0gYygtMTUsIDE1KSkgKwogIHlsYWIoTlVMTCkgKyB4bGFiKCJEYXkgb2YgdGhlIHllYXIiKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMzY1LCA1MCksIGV4cGFuZCA9IGMoMCwgMCkpICsgCiAgbXl0aGVtZSgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG91cmJhcihiYXJoZWlnaHQgPSAwLjUsIGJhcndpZHRoID0gNSwgbGFiZWwucG9zaXRpb24gPSAiYm90dG9tIikpIAoKYm90X2dyYXBoIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZCgKICBzaGFkX2RpZmZfbW9kZWwsIAogIHRyZWVfZGlmZl9tb2RlbCwgCiAgYnVycl9kaWZmX21vZGVsLAogIG5jb2wgPSAxLCBsYWJlbHMgPSBjKCdiJywgJ2QnLCAnZycpLAogIGFsaWduID0gJ3YnLCBheGlzID0gJ2wnKQoKY293cGxvdDo6cGxvdF9ncmlkKHRvcF9ncmFwaCwgYm90X2dyYXBoKQpgYGAKCioqKgoKIyBFeHRlbmRlZCBkYXRhIHstfQoKIyMgRXh0ZW5kZWQgRmlndXJlIDEgLSBQRFNJIGludGVuc2l0eSByaXNrIHstfQoKYGBge3IgRmlnIEUxLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTl9ClBEU0lfMkNfZGlmZl9yYXN0X2Nyb3AgPC0gcmFzdGVyOjptYXNrKGNyb3AoUERTSV8yQ19kaWZmX3Jhc3QsIGV4dGVudCh3b3JsZCkpLCB3b3JsZCkgIyBjcm9wIApQRFNJXzJDX3JvYiA8LSByYXN0ZXI6OnByb2plY3RSYXN0ZXIocmFzdGVyOjpzdGFjayhQRFNJXzJDX2RpZmZfcmFzdF9jcm9wLCByZXNhbXBsZShhbnVyYW5fc3IsIFBEU0lfMkNfZGlmZl9yYXN0X2Nyb3ApKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3JzID0gcm9iX3Byb2opCgpQRFNJXzRDX2RpZmZfcmFzdF9jcm9wIDwtIHJhc3Rlcjo6bWFzayhjcm9wKFBEU0lfNENfZGlmZl9yYXN0LCBleHRlbnQod29ybGQpKSwgd29ybGQpICMgY3JvcCAKUERTSV80Q19yb2IgPC0gcmFzdGVyOjpwcm9qZWN0UmFzdGVyKHJhc3Rlcjo6c3RhY2soUERTSV80Q19kaWZmX3Jhc3RfY3JvcCwgcmVzYW1wbGUoYW51cmFuX3NyLCBQRFNJXzRDX2RpZmZfcmFzdF9jcm9wKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgIGNycyA9IHJvYl9wcm9qKQoKUERTSV8yQ19kZl9yb2IgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV8yQ19yb2IpKSAlPiUKICBkcGx5cjo6cmVuYW1lKGxheWVyID0gZGVsdGFfaW50XzJDLAogICAgICAgICAgICAgICAgc3BlY2llc19uID0gbGF5ZXIpICU+JSAKICBkcGx5cjo6bXV0YXRlKGNoYW5nZSA9IGNhc2Vfd2hlbigKICAgIGxheWVyID49IDQgfiAiNCIsIAogICAgbGF5ZXIgPj0gMyAmIGxheWVyIDwgNCB+ICczJywKICAgIGxheWVyID49IDIgJiBsYXllciA8IDMgfiAnMicsICAKICAgIGxheWVyID49IDEgJiBsYXllciA8IDIgfiAnMScsICAKICAgIGxheWVyID49IC0xICYgbGF5ZXIgPCAxIH4gJzAnLAogICAgbGF5ZXIgPj0gLTIgJiBsYXllciA8IC0xIH4gJy0xJywKICAgIGxheWVyID49IC0zICYgbGF5ZXIgPCAtMiB+ICctMicsCiAgICBsYXllciA+PSAtNCAmIGxheWVyIDwgLTMgfiAnLTMnLCAgIAogICAgbGF5ZXIgPCAtNCB+ICctNCcgCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoY2hhbmdlID0gZmFjdG9yKGNoYW5nZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCctNCcsICctMycsICctMicsICctMScsICcwJywgJzEnLCAnMicsICczJywgJzQnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVFJVRSkpICU+JQogIGRwbHlyOjpmaWx0ZXIoY2hhbmdlICE9ICJOQSIgJiBzcGVjaWVzX24gIT0gIk5BIikKClBEU0lfNENfZGZfcm9iIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKFBEU0lfNENfcm9iKSkgJT4lCiAgZHBseXI6OnJlbmFtZShsYXllciA9IGRlbHRhX2ludF80QywKICAgICAgICAgICAgICAgIHNwZWNpZXNfbiA9IGxheWVyKSAlPiUgCiAgZHBseXI6Om11dGF0ZShjaGFuZ2UgPSBjYXNlX3doZW4oCiAgICBsYXllciA+PSA0IH4gIjQiLCAKICAgIGxheWVyID49IDMgJiBsYXllciA8IDQgfiAnMycsCiAgICBsYXllciA+PSAyICYgbGF5ZXIgPCAzIH4gJzInLCAgCiAgICBsYXllciA+PSAxICYgbGF5ZXIgPCAyIH4gJzEnLCAgCiAgICBsYXllciA+PSAtMSAmIGxheWVyIDwgMSB+ICcwJywKICAgIGxheWVyID49IC0yICYgbGF5ZXIgPCAtMSB+ICctMScsCiAgICBsYXllciA+PSAtMyAmIGxheWVyIDwgLTIgfiAnLTInLAogICAgbGF5ZXIgPj0gLTQgJiBsYXllciA8IC0zIH4gJy0zJywgICAKICAgIGxheWVyIDwgLTQgfiAnLTQnIAogICkpICU+JSAKICBkcGx5cjo6bXV0YXRlKGNoYW5nZSA9IGZhY3RvcihjaGFuZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygnLTQnLCAnLTMnLCAnLTInLCAnLTEnLCAnMCcsICcxJywgJzInLCAnMycsICc0JyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGNoYW5nZSAhPSAiTkEiICYgc3BlY2llc19uICE9ICJOQSIpCgojIEludGVuc2l0eSArMkMgLSBFeCBGaWcuIDFhCmNvbG91cnNfUERTSSA8LSBSQ29sb3JCcmV3ZXI6OmJyZXdlci5wYWwoOSwgIlJkQnUiKQpQRFNJXzJDX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBQRFNJXzJDX2RmX3JvYiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGNoYW5nZSkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvdXJzX1BEU0kpICsKICBnZ25ld3NjYWxlOjpuZXdfc2NhbGUoImZpbGwiKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGhpbGxfZGYgJT4lIGZpbHRlcihoaWxsIDw9IDAuNjQ1KSwgYWVzKGxvbiwgbGF0LCBmaWxsID0gaGlsbCwgYWxwaGEgPSBoaWxsKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImJsYWNrIiwgaGlnaCA9ICJncmV5IikgKwogIHNjYWxlX2FscGhhX2NvbnRpbnVvdXModHJhbnMgPSAicmV2ZXJzZSIpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZShleHByZXNzaW9uKERlbHRhKiJQRFNJIGludGVuc2l0eSAoKzLCsEMpIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjFlNSwgODVlNSksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTVlNiwgMTZlNiksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKIyBJbnRlbnNpdHkgKzRDIC0gRXggRmlnLiAxYwpQRFNJXzRDX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBQRFNJXzRDX2RmX3JvYiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGNoYW5nZSkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvdXJzX1BEU0kpICsKICBnZ25ld3NjYWxlOjpuZXdfc2NhbGUoImZpbGwiKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IGhpbGxfZGYgJT4lIGZpbHRlcihoaWxsIDw9IDAuNjQ1KSwgYWVzKGxvbiwgbGF0LCBmaWxsID0gaGlsbCwgYWxwaGEgPSBoaWxsKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImJsYWNrIiwgaGlnaCA9ICJncmV5IikgKwogIHNjYWxlX2FscGhhX2NvbnRpbnVvdXModHJhbnMgPSAicmV2ZXJzZSIpICsKICB0aGVtZV92b2lkKCkgKyB5bGFiKE5VTEwpICsgeGxhYihOVUxMKSArCiAgZ2d0aXRsZShleHByZXNzaW9uKERlbHRhKiJQRFNJIGludGVuc2l0eSAoKzTCsEMpIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjFlNSwgODVlNSksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTVlNiwgMTZlNiksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKIyAyQyBjaGFuZ2UgLSBFeCBGaWcgMWIKUERTSV9zcF8yQ19wbG90IDwtIFBEU0lfc3BfMkMgJT4lCiAgcm93c19pbnNlcnQodGliYmxlKGNoYW5nZV8yQyA9ICI0IiwgYWxsX2ZyZXEgPSAwKSwgY29uZmxpY3QgPSAiaWdub3JlIikgJT4lCiAgZmlsdGVyKGNoYW5nZV8yQyAhPSAiTkEiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBjaGFuZ2VfMkMsIHkgPSBhbGxfZnJlcSwgZmlsbCA9IGNoYW5nZV8yQykpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG91cnNfUERTSSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChhbGxfZnJlcSwgMSkpLCB2anVzdCA9IC0xLCBzaXplID0gMikgKwogIHlsYWIoIiUgc3BlY2llcyIpICsgeGxhYigiUERTSSIpICsKICB5bGltKDAsIDgwKSArCiAgZ2d0aXRsZSgiR3JpZCBjZWxsIG9jY3VwaWVkICsywrBDIikgKwogIG15dGhlbWUoKSArIAogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkKCiMgNEMgY2hhbmdlIC0gRXggRmlnIDFkClBEU0lfc3BfNENfcGxvdCA8LSBQRFNJX3NwXzRDICU+JQogIGZpbHRlcihjaGFuZ2VfNEMgIT0gIk5BIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gY2hhbmdlXzRDLCB5ID0gYWxsX2ZyZXEsIGZpbGwgPSBjaGFuZ2VfNEMpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvdXJzX1BEU0kpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gcm91bmQoYWxsX2ZyZXEsIDEpKSwgdmp1c3QgPSAtMSwgc2l6ZSA9IDIpICsKICB5bGFiKCIlIHNwZWNpZXMiKSArIHhsYWIoIlBEU0kiKSArCiAgeWxpbSgwLCA4MCkgKwogIGdndGl0bGUoIkdyaWQgY2VsbCBvY2N1cGllZCArNMKwQyIpICsKICBteXRoZW1lKCkgKyAKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpCgpsZWZ0X3Bsb3QgPC0gY293cGxvdDo6cGxvdF9ncmlkKAogIFBEU0lfMkNfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgUERTSV80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBuY29sID0gMSwKICBhbGlnbiA9ICJoIiwgYXhpcyA9ICJidCIsIGxhYmVscyA9IGMoJ2EnLCAnYycsICdlJykpCgpyaWdodF9wbG90IDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZCgKICBQRFNJX3NwXzJDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogIFBEU0lfc3BfNENfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgbmNvbCA9IDEsCiAgYWxpZ24gPSAiaCIsIGF4aXMgPSAiYnQiLCBsYWJlbHMgPSBjKCdiJywgJ2QnLCAnZicpKQoKY293cGxvdDo6cGxvdF9ncmlkKGxlZnRfcGxvdCwgcmlnaHRfcGxvdCwgbmNvbCA9IDIsIHJlbF93aWR0aHMgPSBjKDEsIDAuNykpCmBgYAoKIyMgRXh0ZW5kZWQgRmlndXJlIDIgLSBQRFNJIGZyZXF1ZW5jeSByaXNrIHstfQoKYGBge3IgRmlnIEUyLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTl9CmZyZXFfZGlmZl9yYXN0X2Nyb3AgPC0gcmFzdGVyOjptYXNrKGNyb3AoZnJlcV9kaWZmX3Jhc3QsIGV4dGVudCh3b3JsZCkpLCB3b3JsZCkgIyBjcm9wCgpQRFNJX2ZyZXFfcm9iIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKGZyZXFfZGlmZl9yYXN0X2Nyb3AsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzYW1wbGUoYW51cmFuX3NyLCBmcmVxX2RpZmZfcmFzdF9jcm9wKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNycyA9IHJvYl9wcm9qKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIApQRFNJX2ZyZXFfMkNfZGYgPC0gcmFzdGVyOjphcy5kYXRhLmZyYW1lKHJhc3Rlcjo6cmFzdGVyVG9Qb2ludHMoUERTSV9mcmVxX3JvYikpICU+JQogIGRwbHlyOjptdXRhdGUoZGlmZl8yQ19jYXQgPSBjYXNlX3doZW4oCiAgICBkaWZmXzJDID49IDEwIH4gIjEwLTEyIiwgCiAgICBkaWZmXzJDID49IDggJiBkaWZmXzJDIDwgMTAgfiAnOC0xMCcsCiAgICBkaWZmXzJDID49IDYgJiBkaWZmXzJDIDwgOCB+ICc2LTgnLCAgCiAgICBkaWZmXzJDID49IDQgJiBkaWZmXzJDIDwgNiB+ICc0LTYnLCAgCiAgICBkaWZmXzJDID49IDIgJiBkaWZmXzJDIDwgNCB+ICcyLTQnLAogICAgZGlmZl8yQyA+PSAxICYgZGlmZl8yQyA8IDIgfiAnMS0yJywKICAgIGRpZmZfMkMgPiAwICYgZGlmZl8yQyA8IDEgfiAnMC0xJywKICAgIGRpZmZfMkMgPj0gLTEgJiBkaWZmXzJDIDwgMCB+ICctMC0xJywKICAgIGRpZmZfMkMgPj0gLTIgJiBkaWZmXzJDIDwgLTEgfiAnLTEtMicsCiAgICBkaWZmXzJDID49IC00ICYgZGlmZl8yQyA8IC0yIH4gJy0yLTQnCiAgKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoZGlmZl8yQ19jYXQgPSBmYWN0b3IoZGlmZl8yQ19jYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCcxMC0xMicsICc4LTEwJywgJzYtOCcsICc0LTYnLCAnMi00JywgJzEtMicsICcwLTEnLCctMC0xJywgJy0xLTInLCAnLTItNCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyZWQgPSBUUlVFKSkgJT4lCiAgZHBseXI6OmZpbHRlcihkaWZmXzJDX2NhdCAhPSAiTkEiICYgbGF5ZXIgIT0gIk5BIikKClBEU0lfZnJlcV80Q19kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhQRFNJX2ZyZXFfcm9iKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkaWZmXzRDX2NhdCA9IGNhc2Vfd2hlbigKICAgIGRpZmZfNEMgPj0gMTAgfiAiMTAtMTIiLCAKICAgIGRpZmZfNEMgPj0gOCAmIGRpZmZfNEMgPCAxMCB+ICc4LTEwJywKICAgIGRpZmZfNEMgPj0gNiAmIGRpZmZfNEMgPCA4IH4gJzYtOCcsICAKICAgIGRpZmZfNEMgPj0gNCAmIGRpZmZfNEMgPCA2IH4gJzQtNicsICAKICAgIGRpZmZfNEMgPj0gMiAmIGRpZmZfNEMgPCA0IH4gJzItNCcsCiAgICBkaWZmXzRDID49IDEgJiBkaWZmXzRDIDwgMiB+ICcxLTInLAogICAgZGlmZl80QyA+IDAgJiBkaWZmXzRDIDwgMSB+ICcwLTEnLAogICAgZGlmZl80QyA+PSAtMSAmIGRpZmZfNEMgPCAwIH4gJy0wLTEnLAogICAgZGlmZl80QyA+PSAtMiAmIGRpZmZfNEMgPCAtMSB+ICctMS0yJywKICAgIGRpZmZfNEMgPj0gLTQgJiBkaWZmXzRDIDwgLTIgfiAnLTItNCcKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShkaWZmXzRDX2NhdCA9IGZhY3RvcihkaWZmXzRDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoJzEwLTEyJywgJzgtMTAnLCAnNi04JywgJzQtNicsICcyLTQnLCAnMS0yJywgJzAtMScsICctMC0xJywgJy0xLTInLCAnLTItNCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGRpZmZfNENfY2F0ICE9ICJOQSIgJiBsYXllciAhPSAiTkEiKQoKIyBGcmVxIG1hcCAyQyAtIEZpZyBTMTBhCmZyZXFfMkNfcGxvdCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IFBEU0lfZnJlcV8yQ19kZiwgYWVzKHkgPSB5LCB4ID0geCwgZmlsbCA9IGRpZmZfMkNfY2F0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGRfcm9iLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLCBjb2xvdXIgPSAiIzY0Njg2YiIsIGZpbGwgPSBOQSwgc2l6ZSA9IDAuMSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM2NzAwMUYiLCAiI0IyMTgyQiIsICIjRDY2MDREIiwgIiNGNEE1ODIiLCAiI0ZEREJDNyIsICIjRkFFOURGIiwgIiNGN0Y3RjciLCAiI2RmZWJmMiIpKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbigiQ2hhbmdlIGluIGRyb3VnaHQgZnJlcXVlbmN5ICgiKkRlbHRhKiJQRFNJICsywrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCiMgRnJlcSBtYXAgNEMgLSBGaWcgUzEwYwpmcmVxXzRDX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBQRFNJX2ZyZXFfNENfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBkaWZmXzRDX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiwgIiNkZmViZjIiKSkgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKGV4cHJlc3Npb24oIkNoYW5nZSBpbiBkcm91Z2h0IGZyZXF1ZW5jeSAoIipEZWx0YSoiUERTSSArNMKwQykiKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC02MWU1LCA4NWU1KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xNWU2LCAxNmU2KSwgZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArCiAgY29vcmRfZml4ZWQocmF0aW8gPSAxKSAjIGZpeGVkIHJhdGlvCgojIDJDIGNoYW5nZSAtIEZpZyBTMTBiCmZyZXFfc3BfMkMgPC0gZGF0YS5mcmFtZShQRFNJX2ZyZXFfMkNfZGYgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoZGlmZl8yQ19jYXQpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShzcGVjaWVzX24gPSBsZW5ndGgobGF5ZXJbIWlzLm5hKGxheWVyKV0pKSkgJT4lCiAgZHBseXI6Om11dGF0ZShhbGxfZnJlcSAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCkKCmZyZXFfc3BfMkNfcGxvdCA8LSBmcmVxX3NwXzJDICU+JQogIGdncGxvdChhZXMoeCA9IGRpZmZfMkNfY2F0LCB5ID0gYWxsX2ZyZXEsIGZpbGwgPSBkaWZmXzJDX2NhdCkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiM2NzAwMUYiLCAiI0IyMTgyQiIsICIjRDY2MDREIiwgIiNGNEE1ODIiLCAiI0ZEREJDNyIsICIjRkFFOURGIiwgIiNGN0Y3RjciLCAiI2RmZWJmMiIpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGFsbF9mcmVxLCAxKSksIHZqdXN0ID0gLTEsIHNpemUgPSAyKSArCiAgeWxhYigiJSBzcGVjaWVzIikgKyB4bGFiKCJNb250aHMiKSArCiAgeWxpbSgwLCA2MCkgKwogIGdndGl0bGUoIkdyaWQgY2VsbCBvY2N1cGllZCArMsKwQyIpICsKICBteXRoZW1lKCkgKyAKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpCgojIDRDIGNoYW5nZSAtIEZpZyBTMTBkCmZyZXFfc3BfNEMgPC0gZGF0YS5mcmFtZShQRFNJX2ZyZXFfNENfZGYgJT4lIGRwbHlyOjpncm91cF9ieShkaWZmXzRDX2NhdCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2Uoc3BlY2llc19uID0gbGVuZ3RoKGxheWVyWyFpcy5uYShsYXllcildKSkpICU+JQogIGRwbHlyOjptdXRhdGUoYWxsX2ZyZXEgID0gc3BlY2llc19uIC8gc3VtKHNwZWNpZXNfbikgKiAxMDApCgpmcmVxX3NwXzRDX3Bsb3QgPC0gZnJlcV9zcF80QyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkaWZmXzRDX2NhdCwgeSA9IGFsbF9mcmVxLCBmaWxsID0gZGlmZl80Q19jYXQpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiwgIiNkZmViZjIiKSkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSByb3VuZChhbGxfZnJlcSwgMSkpLCB2anVzdCA9IC0xLCBzaXplID0gMikgKwogIHlsYWIoIiUgc3BlY2llcyIpICsgeGxhYigiTW9udGhzIikgKwogIHlsaW0oMCwgNjApICsKICBnZ3RpdGxlKCJHcmlkIGNlbGwgb2NjdXBpZWQgKzTCsEMiKSArCiAgbXl0aGVtZSgpICsgCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQoKbGVmdF9wbG90MiA8LSBjb3dwbG90OjpwbG90X2dyaWQoCiAgZnJlcV8yQ19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBmcmVxXzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogIG5jb2wgPSAxLAogIGFsaWduID0gImgiLCBheGlzID0gImJ0IiwgbGFiZWxzID0gYygnYScsICdjJykpCgpyaWdodF9wbG90MiA8LSBjb3dwbG90OjpwbG90X2dyaWQoCiAgZnJlcV9zcF8yQ19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBmcmVxX3NwXzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogIG5jb2wgPSAxLAogIGFsaWduID0gImgiLCBheGlzID0gImJ0IiwgbGFiZWxzID0gYygnYicsICdkJykpCgpjb3dwbG90OjpwbG90X2dyaWQobGVmdF9wbG90MiwgcmlnaHRfcGxvdDIsIG5jb2wgPSAyLCByZWxfd2lkdGhzID0gYygxLCAwLjcpKQpgYGAKCiMjIEV4dGVuZGVkIEZpZ3VyZSAzIC0gUERTSSBkdXJhdGlvbiByaXNrIHstfQoKYGBge3IgRmlnIEUzLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTl9ClBEU0lfZHVyX2RpZmZfY3JvcCA8LSByYXN0ZXI6Om1hc2soY3JvcChQRFNJX2R1cl9kaWZmLCBleHRlbnQod29ybGQpKSwgd29ybGQpICMgY3JvcAoKUERTSV9kdXJfcm9iIDwtIHJhc3Rlcjo6cHJvamVjdFJhc3RlcihyYXN0ZXI6OnN0YWNrKFBEU0lfZHVyX2RpZmZfY3JvcCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNhbXBsZShhbnVyYW5fc3IsIFBEU0lfZHVyX2RpZmZfY3JvcCkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcnMgPSByb2JfcHJvaikKClBEU0lfZHVyXzJDX2RmIDwtIHJhc3Rlcjo6YXMuZGF0YS5mcmFtZShyYXN0ZXI6OnJhc3RlclRvUG9pbnRzKFBEU0lfZHVyX3JvYikpICU+JQogIGRwbHlyOjpyZW5hbWUoInNwX24iID0gbGF5ZXIpICU+JQogIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKHNwX24pKSAlPiUKICBkcGx5cjo6bXV0YXRlKGRpZmZfMkNfY2F0ID0gY2FzZV93aGVuKAogICAgZGVsdGFfZHVyXzJDID49IDEwIH4gIj4xMCIsIAogICAgZGVsdGFfZHVyXzJDID49IDggJiBkZWx0YV9kdXJfMkMgPCAxMCB+ICc4LTEwJywKICAgIGRlbHRhX2R1cl8yQyA+PSA2ICYgZGVsdGFfZHVyXzJDIDwgOCB+ICc2LTgnLCAgCiAgICBkZWx0YV9kdXJfMkMgPj0gNCAmIGRlbHRhX2R1cl8yQyA8IDYgfiAnNC02JywgIAogICAgZGVsdGFfZHVyXzJDID49IDIgJiBkZWx0YV9kdXJfMkMgPCA0IH4gJzItNCcsCiAgICBkZWx0YV9kdXJfMkMgPj0gMSAmIGRlbHRhX2R1cl8yQyA8IDIgfiAnMS0yJywKICAgIGRlbHRhX2R1cl8yQyA+IDAgJiBkZWx0YV9kdXJfMkMgPCAxIH4gJzAtMScsCiAgICBkZWx0YV9kdXJfMkMgPj0gLTEgJiBkZWx0YV9kdXJfMkMgPCAwIH4gJy0wLTEnLAogICAgZGVsdGFfZHVyXzJDID49IC0yICYgZGVsdGFfZHVyXzJDIDwgLTEgfiAnLTEtMicsCiAgICBkZWx0YV9kdXJfMkMgPj0gLTQgJiBkZWx0YV9kdXJfMkMgPCAtMiB+ICctMi00JywKICAgIGRlbHRhX2R1cl8yQyA+PSAtOCAmIGRlbHRhX2R1cl8yQyA8IC02IH4gJy02LTgnLAogICAgZGVsdGFfZHVyXzJDID49IC0xMCAmIGRlbHRhX2R1cl8yQyA8IC04IH4gJy04LTEwJywgICAKICAgIGRlbHRhX2R1cl8yQyA8IC0xMCB+ICc8LTEwJyAKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShkaWZmXzJDX2NhdCA9IGZhY3RvcihkaWZmXzJDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc+MTAnLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAiMC0xIiwgJy0wLTEnLCAnLTEtMicsICctMi00JywgJy00LTYnLCAnLTYtOCcsICctOC0xMCcsICc8LTEwJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGRpZmZfMkNfY2F0ICE9ICJOQSIpCgpQRFNJX2R1cl80Q19kZiA8LSByYXN0ZXI6OmFzLmRhdGEuZnJhbWUocmFzdGVyOjpyYXN0ZXJUb1BvaW50cyhQRFNJX2R1cl9yb2IpKSAlPiUKICBkcGx5cjo6cmVuYW1lKCJzcF9uIiA9IGxheWVyKSAlPiUKICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShzcF9uKSkgJT4lCiAgZHBseXI6Om11dGF0ZShkaWZmXzRDX2NhdCA9IGNhc2Vfd2hlbigKICAgIGRlbHRhX2R1cl80QyA+PSAxMCB+ICI+MTAiLCAKICAgIGRlbHRhX2R1cl80QyA+PSA4ICYgZGVsdGFfZHVyXzRDIDwgMTAgfiAnOC0xMCcsCiAgICBkZWx0YV9kdXJfNEMgPj0gNiAmIGRlbHRhX2R1cl80QyA8IDggfiAnNi04JywgIAogICAgZGVsdGFfZHVyXzRDID49IDQgJiBkZWx0YV9kdXJfNEMgPCA2IH4gJzQtNicsICAKICAgIGRlbHRhX2R1cl80QyA+PSAyICYgZGVsdGFfZHVyXzRDIDwgNCB+ICcyLTQnLAogICAgZGVsdGFfZHVyXzRDID49IDEgJiBkZWx0YV9kdXJfNEMgPCAyIH4gJzEtMicsCiAgICBkZWx0YV9kdXJfNEMgPiAwICYgZGVsdGFfZHVyXzRDIDwgMSB+ICcwLTEnLAogICAgZGVsdGFfZHVyXzRDID49IC0xICYgZGVsdGFfZHVyXzRDIDwgMCB+ICctMC0xJywKICAgIGRlbHRhX2R1cl80QyA+PSAtMiAmIGRlbHRhX2R1cl80QyA8IC0xIH4gJy0xLTInLAogICAgZGVsdGFfZHVyXzRDID49IC00ICYgZGVsdGFfZHVyXzRDIDwgLTIgfiAnLTItNCcsCiAgICBkZWx0YV9kdXJfNEMgPj0gLTYgJiBkZWx0YV9kdXJfNEMgPCAtNCB+ICctNC02JywKICAgIGRlbHRhX2R1cl80QyA+PSAtOCAmIGRlbHRhX2R1cl80QyA8IC02IH4gJy02LTgnLAogICAgZGVsdGFfZHVyXzRDID49IC0xMCAmIGRlbHRhX2R1cl80QyA8IC04IH4gJy04LTEwJywgICAKICAgIGRlbHRhX2R1cl80QyA8IC0xMCB+ICc8LTEwJyAKICApKSAlPiUgCiAgZHBseXI6Om11dGF0ZShkaWZmXzRDX2NhdCA9IGZhY3RvcihkaWZmXzRDX2NhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCc+MTAnLCAnOC0xMCcsICc2LTgnLCAnNC02JywgJzItNCcsICcxLTInLCAiMC0xIiwgJy0wLTEnLCAnLTEtMicsICctMi00JywgJy00LTYnLCAnLTYtOCcsICctOC0xMCcsICc8LTEwJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFRSVUUpKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGRpZmZfNENfY2F0ICE9ICJOQSIpCgpkdXJfMkNfcGxvdCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9yYXN0ZXIoZGF0YSA9IFBEU0lfZHVyXzJDX2RmLCBhZXMoeSA9IHksIHggPSB4LCBmaWxsID0gZGlmZl8yQ19jYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZF9yb2IsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksIGNvbG91ciA9ICIjNjQ2ODZiIiwgZmlsbCA9IE5BLCBzaXplID0gMC4xKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzY3MDAxRiIsICIjQjIxODJCIiwgIiNENjYwNEQiLCAiI0Y0QTU4MiIsICIjRkREQkM3IiwgIiNGQUU5REYiLCAiI0Y3RjdGNyIsICIjZGZlYmYyIiwgIiNEMUU1RjAiKSkgKwogIGdnbmV3c2NhbGU6Om5ld19zY2FsZSgiZmlsbCIpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gaGlsbF9kZiAlPiUgZmlsdGVyKGhpbGwgPD0gMC42NDUpLCBhZXMobG9uLCBsYXQsIGZpbGwgPSBoaWxsLCBhbHBoYSA9IGhpbGwpLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYmxhY2siLCBoaWdoID0gImdyZXkiKSArCiAgc2NhbGVfYWxwaGFfY29udGludW91cyh0cmFucyA9ICJyZXZlcnNlIikgKwogIHRoZW1lX3ZvaWQoKSArIHlsYWIoTlVMTCkgKyB4bGFiKE5VTEwpICsKICBnZ3RpdGxlKGV4cHJlc3Npb24oIkNoYW5nZSBpbiBkcm91Z2h0IGR1cmF0aW9uICgiKkRlbHRhKiJQRFNJICsywrBDKSIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTYxZTUsIDg1ZTUpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTE1ZTYsIDE2ZTYpLCBleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsKICBjb29yZF9maXhlZChyYXRpbyA9IDEpICMgZml4ZWQgcmF0aW8KCmR1cl80Q19wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3Jhc3RlcihkYXRhID0gUERTSV9kdXJfNENfZGYsIGFlcyh5ID0geSwgeCA9IHgsIGZpbGwgPSBkaWZmXzRDX2NhdCkpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkX3JvYiwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwgY29sb3VyID0gIiM2NDY4NmIiLCBmaWxsID0gTkEsIHNpemUgPSAwLjEpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiwgIiNkZmViZjIiLCAiI0QxRTVGMCIpKSArCiAgZ2duZXdzY2FsZTo6bmV3X3NjYWxlKCJmaWxsIikgKwogIGdlb21fcmFzdGVyKGRhdGEgPSBoaWxsX2RmICU+JSBmaWx0ZXIoaGlsbCA8PSAwLjY0NSksIGFlcyhsb24sIGxhdCwgZmlsbCA9IGhpbGwsIGFscGhhID0gaGlsbCksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJibGFjayIsIGhpZ2ggPSAiZ3JleSIpICsKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHRyYW5zID0gInJldmVyc2UiKSArCiAgdGhlbWVfdm9pZCgpICsgeWxhYihOVUxMKSArIHhsYWIoTlVMTCkgKwogIGdndGl0bGUoZXhwcmVzc2lvbigiQ2hhbmdlIGluIGRyb3VnaHQgZHVyYXRpb24gKCIqRGVsdGEqIlBEU0kgKzTCsEMpIikpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtNjFlNSwgODVlNSksIGV4cGFuZCA9IGMoMCwgMCkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTVlNiwgMTZlNiksIGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKwogIGNvb3JkX2ZpeGVkKHJhdGlvID0gMSkgIyBmaXhlZCByYXRpbwoKIyAyQyBjaGFuZ2UgLSBGaWcgUzExYgpkdXJfc3BfMkMgPC0gZGF0YS5mcmFtZShQRFNJX2R1cl8yQ19kZiAlPiUgZHBseXI6Omdyb3VwX2J5KGRpZmZfMkNfY2F0KSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiA9IGxlbmd0aChzcF9uWyFpcy5uYShzcF9uKV0pKSkgJT4lCiAgZHBseXI6Om11dGF0ZShhbGxfZnJlcSAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCkKCmR1cl9zcF8yQ19wbG90IDwtIGR1cl9zcF8yQyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkaWZmXzJDX2NhdCwgeSA9IGFsbF9mcmVxLCBmaWxsID0gZGlmZl8yQ19jYXQpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiwgIiNkZmViZjIiLCAiI0QxRTVGMCIpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGFsbF9mcmVxLCAxKSksIHZqdXN0ID0gLTEsIHNpemUgPSAyKSArCiAgeWxhYigiJSBzcGVjaWVzIikgKyB4bGFiKCJNb250aHMiKSArCiAgeWxpbSgwLCA1MCkgKwogIGdndGl0bGUoIkdyaWQgY2VsbCBvY2N1cGllZCArMsKwQyIpICsKICBteXRoZW1lKCkgKyAKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpCgojIDRDIGNoYW5nZSAtIEZpZyBTMTFkCmR1cl9zcF80QyA8LSBkYXRhLmZyYW1lKFBEU0lfZHVyXzRDX2RmICU+JSBkcGx5cjo6Z3JvdXBfYnkoZGlmZl80Q19jYXQpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHNwZWNpZXNfbiA9IGxlbmd0aChzcF9uWyFpcy5uYShzcF9uKV0pKSkgJT4lCiAgZHBseXI6Om11dGF0ZShhbGxfZnJlcSAgPSBzcGVjaWVzX24gLyBzdW0oc3BlY2llc19uKSAqIDEwMCkKCmR1cl9zcF80Q19wbG90IDwtIGR1cl9zcF80QyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkaWZmXzRDX2NhdCwgeSA9IGFsbF9mcmVxLCBmaWxsID0gZGlmZl80Q19jYXQpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjcwMDFGIiwgIiNCMjE4MkIiLCAiI0Q2NjA0RCIsICIjRjRBNTgyIiwgIiNGRERCQzciLCAiI0ZBRTlERiIsICIjRjdGN0Y3IiwgIiNkZmViZjIiLCAiI0QxRTVGMCIpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKGFsbF9mcmVxLCAxKSksIHZqdXN0ID0gLTEsIHNpemUgPSAyKSArCiAgeWxhYigiJSBzcGVjaWVzIikgKyB4bGFiKCJNb250aHMiKSArCiAgeWxpbSgwLCA1MCkgKwogIGdndGl0bGUoIkdyaWQgY2VsbCBvY2N1cGllZCArNMKwQyIpICsKICBteXRoZW1lKCkgKyAKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpCgpsZWZ0X3Bsb3QzIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZCgKICBkdXJfMkNfcGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksCiAgZHVyXzRDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogIG5jb2wgPSAxLAogIGFsaWduID0gImgiLCBheGlzID0gImJ0IiwgbGFiZWxzID0gYygnYScsICdjJykpCgpyaWdodF9wbG90MyA8LSBjb3dwbG90OjpwbG90X2dyaWQoCiAgZHVyX3NwXzJDX3Bsb3QgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpLAogIGR1cl9zcF80Q19wbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBuY29sID0gMSwKICBhbGlnbiA9ICJoIiwgYXhpcyA9ICJidCIsIGxhYmVscyA9IGMoJ2InLCAnZCcpKQoKY293cGxvdDo6cGxvdF9ncmlkKGxlZnRfcGxvdDMsIHJpZ2h0X3Bsb3QzLCBuY29sID0gMiwgcmVsX3dpZHRocyA9IGMoMSwgMC43KSkKYGBgCgoKIyMgRXh0ZW5kZWQgRmlndXJlIDQgLSBXYXRlciB1cHRha2Ugey19CgpgYGB7ciBGaWcgRTQsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD0zLCBmaWcud2lkdGg9NX0KaHlkcl9jb25kaXRpb25zIDwtIGxpc3QoaHlkcmF0aW9uID0gc2V0TmFtZXMoYyg3MCwgODAsIDkwLCAxMDApLCBjKDcwLCA4MCwgOTAsIDEwMCkpKQp3dV9jZSA8LSBjb25kaXRpb25hbF9lZmZlY3RzKHd1X21vZGVsLCBlZmZlY3RzID0gImxuTWFzczpoeWRyYXRpb24iLCBpbnRfY29uZGl0aW9ucyA9IGh5ZHJfY29uZGl0aW9ucykKCnd1X2NlIDwtIGRhdGEuZnJhbWUod3VfY2VbWzFdXSkgJT4lCiAgZHBseXI6OnJlbmFtZShlc3RpbWF0ZSA9IGVzdGltYXRlX18sCiAgICAgICAgICAgICAgICBoeWRyYXRpb25fY2FsID0gZWZmZWN0Ml9fKSAlPiUKICBkcGx5cjo6bXV0YXRlKG1lYW5fbWFzc19nID0gZXhwKGxuTWFzcyksCiAgICAgICAgICAgICAgICBoeWRyYXRpb25fY2FsID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoaHlkcmF0aW9uX2NhbCkpKQoKd3VfZGF0ICU+JQogIGdncGxvdCgpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gbWVhbl9tYXNzX2csIHkgPSBtZ19oX21lYW4pLCAgc2l6ZSA9IDIsIHNoYXBlID0gMjEsIGZpbGwgPSAid2hpdGUiKSArCiAgZ2VvbV9saW5lKGRhdGEgPSB3dV9jZSwgYWVzKHggPSBtZWFuX21hc3NfZywgeSA9IGV4cChlc3RpbWF0ZSksIGdyb3VwID0gaHlkcmF0aW9uLCBjb2xvdXIgPSBoeWRyYXRpb24pLCBzaXplID0gMSkgKwogIGdlb21fdGV4dChkYXRhID0gd3VfY2UgJT4lIGZpbHRlcihtZWFuX21hc3NfZyA9PSBsYXN0KG1lYW5fbWFzc19nKSksIAogICAgICAgICAgICBhZXMobGFiZWwgPSBoeWRyYXRpb24sIAogICAgICAgICAgICAgICAgeCA9IG1lYW5fbWFzc19nICsgNTAsIAogICAgICAgICAgICAgICAgeSA9IGV4cChlc3RpbWF0ZSksCiAgICAgICAgICAgICAgICBoanVzdCA9IC0wLjAxKSwKICAgICAgICAgICAgc2l6ZSA9IDMpICsKICBsYWJzKHggPSAiQm9keSBtYXNzIChnKSIsIGNvbG91ciA9ICJJbml0aWFsIGh5ZHJhdGlvbiAoJSkiKSArCiAgeWxhYihleHByZXNzaW9uKCJXVSJ+KCJtZyJ+SFsyXSpPfmheeyItMSJ9KSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSBzY2FsZXM6OmxvZ190cmFucygpLCBicmVha3MgPSBjKDEwLCAxMDAsIDEwMDAsIDEwMDAwLCAxMDAwMDApLCBsYWJlbHMgPSBjKDEwLCAxMDAsICIxLDAwMCIsICIxMCwwMDAiLCAiMTAwLDAwMCIpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKHRyYW5zID0gJ2xvZzEwJykgKwogIHNjYWxlX2NvbG91cl9ncmFkaWVudDIobG93ID0gIiMwRTNGNUMiLCBtaWQgPSAiIzJBNkQ3QSIsIGhpZ2ggPSAiIzhGQ0NCNCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgbWlkcG9pbnQgPSA4NSkgKwogIGV4cGFuZF9saW1pdHMoeCA9IDUwMCkgKwogIG15dGhlbWUoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2NvbG91cmJhcihiYXJoZWlnaHQgPSAwLjUsIGJhcndpZHRoID0gMTAsIHRpdGxlLnBvc2l0aW9uID0gInRvcCIpKQpgYGAKCioqKgoKIyBBZGRpdGlvbmFsIGZpZ3VyZXMgey19CgpgYGB7ciBmaWcgUzExLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTZ9CnRlbXBfZGF0IDwtIGV3bF9kYXQgJT4lIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKHRydF90ZW1wKSkKCnRlbXBfZGF0ICU+JQogIGdncGxvdChhZXMoeCA9IHRydF90ZW1wLCB5ID0gc2tpbl90ZW1wKSkgKwogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDAuNSkgKwogIGdncG1pc2M6OnN0YXRfcG9seV9saW5lKG1ldGhvZCA9ICJsbSIsIGZvcm11bGEgPSB5IH4geCArIEkoeF42KSwgc2UgPSBGLCBjb2xvciA9ICJibGFjayIpICsKICBnZ3BtaXNjOjpzdGF0X3BvbHlfZXEobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiB4ICsgSSh4XjYpLCAKICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbWlzYzo6dXNlX2xhYmVsKGMoImVxIiwgIlIyIiwgIm4iKSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAyLCBzaGFwZSA9IDIxLCBmaWxsID0gIndoaXRlIikgKwogIHlsaW0oNSw1MCkgKyB4bGltKDUsNTApICsKICBsYWJzKHggPSAiQWlyIHRlbXBlcmF0dXJlICjCsEMpIiwgeSA9ICJTa2luIHN1cmZhY2UgdGVtcGVyYXR1cmUgKMKwQykiKSArCiAgbXl0aGVtZSgpCmBgYAoKKipGaWcuIFMxMS4qKiBSZWxhdGlvbnNoaXAgYmV0d2VlbiBleHBvc2VkIGFpciB0ZW1wZXJhdHVyZSAowrBDKSBkdXJpbmcgdGhlIGV4cGVyaW1lbnQgYW5kIHRoZSBvYnNlcnZlZCBza2luIHN1cmZhY2UgdGVtcGVyYXR1cmUgKMKwQykgYWNyb3NzIGByIGxlbmd0aCh1bmlxdWUodGVtcF9kYXQkc3BlY2llc19waHlsbykpYCBzcGVjaWVzLiBUaGUgYmxhY2sgbGluZSByZXByZXNlbnRzIHRoZSBub24tbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGFpciB0ZW1wZXJhdHVyZSBhbmQgc2tpbiB0ZW1wZXJhdHVyZSB3aGVyZSB0aGUgc2tpbiB0ZW1wZXJhdHVyZSByZW1haW5zIGF0IH4zNcKwQyB3aGVuIGV4cG9zZWQgdG8gYWlyIHRlbXBlcmF0dXJlcyA+IDQwwrBDLgoKYGBge3IgZmlnIFMxMiwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTMuNiwgZmlnLndpZHRoPTZ9CnJhd19kYXQgJT4lCiAgZHBseXI6OmZpbHRlcih0cmFpdCAhPSAid2F0ZXIgZ2FpbiIgJiAhaXMubmEodW5pdF9jb3JyZWN0ZWRfbWVhbikpICU+JQogIGdncGxvdChhZXMoeCA9IHVuaXRfY29ycmVjdGVkX21lYW4sIHkgPSByX3NfZXN0LCBmaWxsID0gY2FsY3VsYXRlZCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAyLCBzaGFwZSA9IDIxLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIHhsYWIoZXhwcmVzc2lvbigiRVdMIn4oIm1nIn4iSCJbMl0qT35oXnsiLTEifSkpKSArCiAgeWxhYihleHByZXNzaW9uKGl0YWxpYygiciIpWyJpIl1+IihzIGNtIl57LTF9KiIpIikpICsKICBsYWJzKGZpbGwgPSBleHByZXNzaW9uKCJFc3RpbWF0ZWQifml0YWxpYygiciIpWyJpIl0pKSArCiAgc2NhbGVfeF9sb2cxMChicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54KSwKICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsKICBzY2FsZV95X2xvZzEwKGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngpLAogICAgICAgICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKwogIGFubm90YXRpb25fbG9ndGlja3MoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygid2hpdGUiLCAiZ3JleSIpKSArCiAgbXl0aGVtZSgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgoqKkZpZy4gUzEyLioqIFJlbGF0aW9uc2hpcCBiZXR3ZWVuIGV2YXBvcmF0aXZlIHdhdGVyIGxvc3MgKEVXTDsgbWcgSH4yfk8gY21e4oiSMl4gaF7iiJIxXikgYW5kIHJlc2lzdGFuY2UgdG8gd2F0ZXIgbG9zcyAoJHJfaSQ7IHMgY21eLTFeKSBvbiBhIGJhc2UtMTAgbG9nYXJpdGhtaWMgc2NhbGUuIE1lYXN1cmVkICRyX2kkIGZyb20gdGhlIHN0dWR5IHByZXNlbnRlZCBhcyB3aGl0ZSBwb2ludHMsIGFuZCB0aGUgZXN0aW1hdGVkICRyX2kkIGZyb20gRVdMIGluIGdyZXkgcG9pbnRzLgoKYGBge3IgRmlnIHMxMywgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD04fQpFV0xfc3BfbG9uZyA8LSBFV0xfc3BfZGYgJT4lIAogIGRwbHlyOjpzZWxlY3QoLXNwZWNpZXNfbikgJT4lCiAgdGlkeXI6OnBpdm90X2xvbmdlcighYyh4LCB5LCBFV0wpLCBuYW1lc190byA9ICJlY290eXBlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgZHBseXI6Om11dGF0ZShlY290eXBlID0gZmFjdG9yKGVjb3R5cGUsIGxldmVscyA9IGMoImZvc3Nfc3AiLCAiZ3Jvbl9zcCIsICJhcXVhX3NwIiwgImFyYm9fc3AiLCAic2VtaV9zcCIsICJzdHJtX3NwIikpKQoKZWNvdHlwZV9sYWJzIDwtIGMoIkZvc3NvcmlhbCIsICJHcm91bmQtZHdlbGxpbmciLCAiQXF1YXRpYyIsICJBcmJvcmVhbCIsICJTZW1pLWFxdWF0aWMiLCAiU3RyZWFtLWR3ZWxsaW5nIikKbmFtZXMoZWNvdHlwZV9sYWJzKSA8LSBjKCJmb3NzX3NwIiwgImdyb25fc3AiLCAiYXF1YV9zcCIsICJhcmJvX3NwIiwgInNlbWlfc3AiLCAic3RybV9zcCIpCgpFV0xfc3BfbG9uZyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBFV0wsIHkgPSBjb3VudCkpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gdHJhbnNmb3JtKEVXTF9zcF9sb25nLCBlY290eXBlID0gTlVMTCksCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTg1IikgKyBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBlY290eXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjUsIHNob3cubGVnZW5kID0gRikgKyB4bGFiKGV4cHJlc3Npb24oIkVXTCIgfiAoImciIH4gSFsyXSAqIE8gfiBoXnsiLTEifSkpKSArIAogIHlsYWIoTlVMTCkgKyAKICBzY2FsZV9jb2xvdXJfdmlyaWRpc19kKCkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMywgMC41KSwgZXhwYW5kID0gYygwLCAwKSkgKyAKICBmYWNldF93cmFwKHZhcnMoZWNvdHlwZSksIGxhYmVsbGVyID0gbGFiZWxsZXIoZWNvdHlwZSA9IGVjb3R5cGVfbGFicykpICsgCiAgbXl0aGVtZSgpCmBgYAoKKipGaWcuIFMxMy4qKiBSZWxhdGlvbnNoaXAgYmV0d2VlbiBFV0wgYW5kIHNwZWNpZXMgcmljaG5lc3MgYnkgZWNvdHlwZS4gR3JleSBwb2ludHMgcmVwcmVzZW50IHRoZSB0b3RhbCBkYXRhc2V0IGFzIGNvbXBhcmlzb24gZm9yIHdoZXJlIGVhY2ggZWNvdHlwZSBmaXRzLgoKKioqCgojIFJlZmVyZW5jZXMgey19Cgo8ZGl2IGlkPSJyZWZzIj48L2Rpdj4KPGJyPgoKKioqCgojIyBTZXNzaW9uIEluZm9ybWF0aW9uIHstfQoKYGBge3Igc2Vzc2lvbmluZm8sIGVjaG8gPSBGQUxTRX0KcGFuZGVyOjpwYW5kZXIoc2Vzc2lvbkluZm8oKSwgbG9jYWxlID0gRkFMU0UpCmBgYA==